使用自定义注解翻译字典项

使用自定义注解翻译字典项

思路:
使用aop的拦截器拦截所有controller的所有返回类型为Ajaxresult和TableDataInfo的方法,查询其内的全部T实体对象,查找添加了@Dict注解的属性,每个属性去查询一遍字典值,再重新注入T实体对象返回。

1.自定义注解类:

Dict.java

package com.leomoon.common.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author: limaopeng
 * 需要引入DictAspect.java拦截器往Controller的TableDataInfo和AjaxResult返回结果的实体注入字典翻译
 * @Description:
 * @Date: 2020/11/20
 */

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Dict {
     
    /**
     * 方法描述:数据类型dictType
     * @return 返回类型: String
     */
    String dictType();

    /**
     * 方法描述:这是返回后Put到josn中的文本key值
     * @return 返回类型: String
     */
    String dictLabel() default "";
}

2.AOP切面拦截注入:

DictAspect.java

package com.leomoon.common.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.leomoon.common.annotation.Dict;
import com.leomoon.common.core.domain.AjaxResult;
import com.leomoon.common.core.domain.TableDataInfo;
import com.leomoon.commoon.DictDataFeign;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @Author: limaopeng
 * @Description:
 * @Date: Create in 11:26 2020/11/20
 */
@Aspect
@Component
@Slf4j
public class DictAspect {
     

    //表对应字段加上DictLabel即可显示出文本
    private static String DICT_TEXT_SUFFIX = "_DictLabel";

    @Autowired
    private DictDataFeign dictDataFeign;

    /**
     * 定义切点Pointcut拦截所有对服务器的请求
     */
    @Pointcut("execution(* com.leomoon..controller..*(..))")
    public void excudeService() {
     

    }

    /**
     * 这是触发DictionariesService的时候会执行的,在环绕通知中目标对象方法被调用后的结果进行再处理
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around("excudeService()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
     
        //这是定义开始事件
        long time1 = System.currentTimeMillis();
        //这是方法并获取返回结果
        Object result = pjp.proceed();
        //这是获取到结束时间
        long time2 = System.currentTimeMillis();
        log.info("获取JSON数据耗时:" + (time2 - time1) + "ms");
        //解析开始时间
        long start = System.currentTimeMillis();
        //开始解析(翻译字段内部的值凡是打了@Dict这玩意的都会被翻译)
        this.parsedictLabel(result);
        //解析结束时间
        long end = System.currentTimeMillis();
        log.info("解析注入JSON数据耗时:" + (end - start) + "ms");
        return result;
    }


    private void parsedictLabel(Object result) {
     
        if (result instanceof TableDataInfo) {
     
            List<JSONObject> items = new ArrayList<>();
            TableDataInfo pageUtils = (TableDataInfo) result;
            //循环查找出来的数据
            for (Object record : pageUtils.getRows()) {
     
                ObjectMapper mapper = new ObjectMapper();
                String json = "{}";
                try {
     
                    //解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
                    json = mapper.writeValueAsString(record);
                } catch (JsonProcessingException e) {
     
                    log.error("Json解析失败:" + e);
                }
                JSONObject item = JSONObject.parseObject(json);

                //解决继承实体字段无法翻译问题
                for (Field field : getAllFields(record)) {
     
                    //解决继承实体字段无法翻译问题
                    if (field.getAnnotation(Dict.class) != null) {
     //如果该属性上面有@Dict注解,则进行翻译
                        String dictType = field.getAnnotation(Dict.class).dictType();//拿到注解的dictType属性的值
                        String text = field.getAnnotation(Dict.class).dictLabel();//拿到注解的dictLabel属性的值
                        //获取当前带翻译的值
                        String key = String.valueOf(item.get(field.getName()));
                        //翻译字典值对应的text值
                        String textValue = translateDictValue(dictType, key);
                        //DICT_TEXT_SUFFIX的值为,是默认值:
                        //public static final String DICT_TEXT_SUFFIX = "_dictLabel";
                        log.debug("字典Val: " + textValue);
                        log.debug("翻译字典字段:" + field.getName() + DICT_TEXT_SUFFIX + ": " + textValue);
                        //如果给了文本名
                        if (!StringUtils.isBlank(text)) {
     
                            item.put(text, textValue);
                        } else {
     
                            //走默认策略
                            item.put(field.getName() + DICT_TEXT_SUFFIX, textValue);
                        }
                    }
                    //date类型默认转换string格式化日期
                    if (field.getType().getName().equals("java.util.Date") && field.getAnnotation(JsonFormat.class) == null && item.get(field.getName()) != null) {
     
                        SimpleDateFormat aDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));
                    }
                }
                items.add(item);
            }
            pageUtils.setRows(items);
        } else if (result instanceof AjaxResult) {
     

            AjaxResult bean = (AjaxResult) result;
            //循环查找出来的数据
            Object record = bean.getData();
            ObjectMapper mapper = new ObjectMapper();
            String json = "{}";
            try {
     
                //解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
                json = mapper.writeValueAsString(record);
            } catch (JsonProcessingException e) {
     
                log.error("Json解析失败:" + e);
            }
            JSONObject item = JSONObject.parseObject(json);

            //解决继承实体字段无法翻译问题
            for (Field field : getAllFields(record)) {
     
                //解决继承实体字段无法翻译问题
                if (field.getAnnotation(Dict.class) != null) {
     //如果该属性上面有@Dict注解,则进行翻译
                    String dictType = field.getAnnotation(Dict.class).dictType();//拿到注解的dictType属性的值
                    String text = field.getAnnotation(Dict.class).dictLabel();//拿到注解的dictLabel属性的值
                    //获取当前带翻译的值
                    String key = String.valueOf(item.get(field.getName()));
                    //翻译字典值对应的text值
                    String textValue = translateDictValue(dictType, key);
                    //DICT_TEXT_SUFFIX的值为,是默认值:
                    //public static final String DICT_TEXT_SUFFIX = "_dictLabel";
                    log.debug("字典Val: " + textValue);
                    log.debug("翻译字典字段:" + field.getName() + DICT_TEXT_SUFFIX + ": " + textValue);
                    //如果给了文本名
                    if (!StringUtils.isBlank(text)) {
     
                        item.put(text, textValue);
                    } else {
     
                        //走默认策略
                        item.put(field.getName() + DICT_TEXT_SUFFIX, textValue);
                    }
                }
                //date类型默认转换string格式化日期
                if (field.getType().getName().equals("java.util.Date") && field.getAnnotation(JsonFormat.class) == null && item.get(field.getName()) != null) {
     
                    SimpleDateFormat aDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));
                }
            }

            bean.setData(record);
        }
    }


    /**
     * 翻译字典文本
     * @param dictType
     * @param key
     * @return
     */
    private String translateDictValue(String dictType, String key) {
     
        //如果key为空直接返回就好了
        if (isEmpty(key)) {
     
            return null;
        }
        StringBuffer textValue = new StringBuffer();
        //分割key值
        String[] keys = key.split(",");
        //循环keys中的所有值
        for (String k : keys) {
     
            String tmpValue = null;
            log.debug("字典key:" + k);
            if (k.trim().length() == 0) {
     
                continue;//跳过循环
            }
            tmpValue = dictDataFeign.dataLabel(dictType, k.trim());

            if (tmpValue != null) {
     
                if (!"".equals(textValue.toString())) {
     
                    textValue.append(",");
                }
                textValue.append(tmpValue);
            }
        }
        //返回翻译的值
        return textValue.toString();
    }

    public static Field[] getAllFields(Object object) {
     
        Class<?> clazz = object.getClass();
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null) {
     
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }

    public static boolean isEmpty(Object object) {
     
        if (object == null) {
     
            return (true);
        }
        if ("".equals(object)) {
     
            return (true);
        }
        if ("null".equals(object)) {
     
            return (true);
        }
        return (false);
    }
}

3.实体调用

User.java

package com.leomoon.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.leomoon.common.annotation.Dict;
import lombok.Data;

/**
 *
 * @author limaopeng
 * @date 2020-11-08 16:32
 */
@Data
@TableName("user")
public class EmphasisObject{
     

    @TableId(type = IdType.UUID)
    private String id;

    @Dict(dictType="user_type",dictLabel = "userTypeLabel")
    private String userType;
}

4.返回结果
json:

    {
     
      "id": "1",
      "userType": "1",
      "userTypeLabel": "普通用户"
    }

你可能感兴趣的:(Spring全家桶,java)