字典 | springboot 返回数据字典翻译

1.前言

在处理完数据返回前端时,通常需要做字典翻译,此时就需要一个好用的处理工具,但是依然不方便,对此,再次封装了一次。

原理 在接口返回时拦截 --- 反射获取对应字典信息 -- 查询字典值 --- 再次塞入对象里面 --- 返回信息

2.代码

字典类型处理
import java.lang.annotation.*;

/**
 * 字典类型处理 拦截
 * <p>常用返回类型处理,不进行四层深层处理</p>
 *
 * @author wbw
 * @date 2020/11/10 11:40
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DictTypeSensible {
    /**
     * 实体类字段
     */
    String value();

    /**
     * 字典code,默认使用 value 转下划线形式
     */
    String code() default "";

}
多个字典值
import java.lang.annotation.*;

/**
 * 多个字典值
 *
 * @author wbw
 * @date 2020/11/1316:53
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DictTypeSensibles {
    /**
     * 多个字典值
     *
     * @return 多个值
     */
    DictTypeSensible[] value();
}
字典拦截转换处理
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gl.common.core.domain.AjaxResult;
import com.gl.common.data.page.TableDataInfo;
import com.gl.common.data.vo.R;
import com.gl.core.annotation.DictTypeSensible;
import com.gl.core.annotation.DictTypeSensibles;
import com.gl.system.service.ISysDictDataService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 字典拦截转换处理
 *
 * @author wbw
 * @date 2020/11/10 17:55
 */
@ControllerAdvice
@AllArgsConstructor
@Slf4j
public class DictTypeSensibleAspect implements ResponseBodyAdvice<Object> {

    private final ISysDictDataService dictDataService;

    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        return methodParameter.hasMethodAnnotation(DictTypeSensible.class)
                || methodParameter.hasMethodAnnotation(DictTypeSensibles.class);
    }

    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType
            , Class clazz, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if (ObjectUtil.isEmpty(o)) {
            return null;
        }
        // 获取方法 注解参数
        Method method = methodParameter.getMethod();
        final String methodName = method == null ? ""
                : (method.getDeclaringClass().getSimpleName() + "." + method.getName());
        DictTypeSensible[] sensibles;
        if (methodParameter.hasMethodAnnotation(DictTypeSensible.class)) {
            DictTypeSensible sensible = methodParameter.getMethodAnnotation(DictTypeSensible.class);
            sensibles = new DictTypeSensible[]{sensible};
        } else {
            DictTypeSensibles typeSensibles = methodParameter.getMethodAnnotation(DictTypeSensibles.class);
            sensibles = typeSensibles == null ? new DictTypeSensible[]{} : typeSensibles.value();
        }
        // 处理返回值
        this.dis(o, sensibles, methodName);
        return o;
    }

    /**
     * 处理返回数据
     *
     * @param obj       对象
     * @param sensibles 字典类型
     */
    private void dis(Object obj, DictTypeSensible[] sensibles, String methodName) {
        // 处理返回类型
        if (obj instanceof TableDataInfo) {
            this.dis(((TableDataInfo) obj).getRows(), sensibles, methodName);
            return;
        }
        if (obj instanceof AjaxResult) {
            this.dis(((AjaxResult) obj).get(AjaxResult.DATA_TAG), sensibles, methodName);
            return;
        }
        if (obj instanceof R) {
            this.dis(((R) obj).getData(), sensibles, methodName);
            return;
        }
        if (obj instanceof IPage) {
            ((IPage) obj).getRecords().forEach(e -> this.dis(e, sensibles, methodName));
            return;
        }
        if (obj instanceof Iterable) {
            ((Iterable) obj).forEach(e -> this.dis(e, sensibles, methodName));
            return;
        }
        if (obj instanceof Map) {
            Map<String, Object> map = (Map<String, Object>) obj;
            for (DictTypeSensible sensible : sensibles) {
                if (!map.containsKey(sensible.value())) {
                    log.warn("--- 方法 {},字典 {} 进行忽略,不存在 ------", methodName, sensible.value());
                    continue;
                }
                Object o = map.get(sensible.value());
                if (o instanceof Iterable) {
                    this.dis(o, sensibles, methodName);
                    continue;
                }
                String code = StrUtil.isEmpty(sensible.code())
                        ? StrUtil.toUnderlineCase(sensible.value()) : sensible.code();
                String label = dictDataService.selectDictLabel(code, String.valueOf(o));
                map.put(sensible.value(), label);
            }
            return;
        }
        Class<?> clazz = obj.getClass();
        for (DictTypeSensible sensible : sensibles) {
            try {
                Field field = ReflectUtil.getField(clazz, sensible.value());
                if (field == null || !field.getType().getSimpleName().contains("String")) {
                    log.warn("--- 方法 {},字典 {} 进行忽略,不存在 || 非String类型 ------", methodName, sensible.value());
                    continue;
                }
                Object val = ReflectUtil.getFieldValue(obj, field);
                if (ObjectUtil.isEmpty(val)) {
                    continue;
                }
                String code = StrUtil.isEmpty(sensible.code())
                        ? StrUtil.toUnderlineCase(sensible.value()) : sensible.code();
                String label = dictDataService.selectDictLabel(code, String.valueOf(val));
                ReflectUtil.setFieldValue(obj, field, label);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

3.使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值