Jeecgboot 字典值自动转化:DictAspect类方法改造,支持IPage、List、Object、Map类自动转化,附有源码

改造的是DictAspect类:

原来使用的 parseDictText(Object result)方法,针对返回对象为Result 的IPage的分页列表数据进行动态字典注入,当单个对象查询,列表查询,或者多个数据放到Map中时,就不会自动转化,在web端进行展示的时候就需要连表查询或者手动查询字典值,不方便使用。

于是我改造了parseDictText()方法,不仅针对返回对象为Result时的分页列表,还支持列表、对象以及Map类型的结果。实在Result对象执行setResult()方式时进行自动注入转换。

原方法

代码:

private Object parseDictText(Object result) {
        //if (result instanceof Result) {
        if (true) {
            if (((Result) result).getResult() instanceof IPage) {
                List<JSONObject> items = new ArrayList<>();

                //step.1 筛选出加了 Dict 注解的字段列表
                List<Field> dictFieldList = new ArrayList<>();
                // 字典数据列表, key = 字典code,value=数据列表
                Map<String, List<String>> dataListMap = new HashMap<>(5);
                //取出结果集
                List<Object> records=((IPage) ((Result) result).getResult()).getRecords();
                //update-begin--Author:zyf -- Date:20220606 ----for:【VUEN-1230】 判断是否含有字典注解,没有注解返回-----
                Boolean hasDict= checkHasDict(records);
                if(!hasDict){
                    return result;
                }

                log.debug(" __ 进入字典翻译切面 DictAspect ------ " );
                //update-end--Author:zyf -- Date:20220606 ----for:【VUEN-1230】 判断是否含有字典注解,没有注解返回-----
                for (Object record : records) {
                    String json="{}";
                    try {
                        //update-begin--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错-----
                        //解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
                         json = objectMapper.writeValueAsString(record);
                        //update-end--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错-----
                    } catch (JsonProcessingException e) {
                        log.error("json解析失败"+e.getMessage(),e);
                    }
                    //update-begin--Author:scott -- Date:20211223 ----for:【issues/3303】restcontroller返回json数据后key顺序错乱 -----
                    JSONObject item = JSONObject.parseObject(json, Feature.OrderedField);
                    //update-end--Author:scott -- Date:20211223 ----for:【issues/3303】restcontroller返回json数据后key顺序错乱 -----

                    //update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
                    //for (Field field : record.getClass().getDeclaredFields()) {
                    // 遍历所有字段,把字典Code取出来,放到 map 里
                    for (Field field : oConvertUtils.getAllFields(record)) {
                        String value = item.getString(field.getName());
                        if (oConvertUtils.isEmpty(value)) {
                            continue;
                        }
                    //update-end--Author:scott  -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
                        if (field.getAnnotation(Dict.class) != null) {
                            if (!dictFieldList.contains(field)) {
                                dictFieldList.add(field);
                            }
                            String code = field.getAnnotation(Dict.class).dicCode();
                            String text = field.getAnnotation(Dict.class).dicText();
                            String table = field.getAnnotation(Dict.class).dictTable();
                            //update-begin---author:chenrui ---date:20231221  for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
                            String dataSource = field.getAnnotation(Dict.class).ds();
                            //update-end---author:chenrui ---date:20231221  for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
                            List<String> dataList;
                            String dictCode = code;
                            if (!StringUtils.isEmpty(table)) {
                                //update-begin---author:chenrui ---date:20231221  for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
                                dictCode = String.format("%s,%s,%s,%s", table, text, code, dataSource);
                                //update-end---author:chenrui ---date:20231221  for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
                            }
                            dataList = dataListMap.computeIfAbsent(dictCode, k -> new ArrayList<>());
                            this.listAddAllDeduplicate(dataList, Arrays.asList(value.split(",")));
                        }
                        //date类型默认转换string格式化日期
                        //update-begin--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错-----
                        //if (JAVA_UTIL_DATE.equals(field.getType().getName())&&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()))));
                        //}
                        //update-end--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错-----
                    }
                    items.add(item);
                }

                //step.2 调用翻译方法,一次性翻译
                Map<String, List<DictModel>> translText = this.translateAllDict(dataListMap);

                //step.3 将翻译结果填充到返回结果里
                for (JSONObject record : items) {
                    for (Field field : dictFieldList) {
                        String code = field.getAnnotation(Dict.class).dicCode();
                        String text = field.getAnnotation(Dict.class).dicText();
                        String table = field.getAnnotation(Dict.class).dictTable();
                        //update-begin---author:chenrui ---date:20231221  for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
                        // 自定义的字典表数据源
                        String dataSource = field.getAnnotation(Dict.class).ds();
                        //update-end---author:chenrui ---date:20231221  for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
                        String fieldDictCode = code;
                        if (!StringUtils.isEmpty(table)) {
                            //update-begin---author:chenrui ---date:20231221  for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
                            fieldDictCode = String.format("%s,%s,%s,%s", table, text, code, dataSource);
                            //update-end---author:chenrui ---date:20231221  for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
                        }

                        String value = record.getString(field.getName());
                        if (oConvertUtils.isNotEmpty(value)) {
                            List<DictModel> dictModels = translText.get(fieldDictCode);
                            if(dictModels==null || dictModels.size()==0){
                                continue;
                            }

                            String textValue = this.translDictText(dictModels, value);
                            log.debug(" 字典Val : " + textValue);
                            log.debug(" __翻译字典字段__ " + field.getName() + CommonConstant.DICT_TEXT_SUFFIX + ": " + textValue);

                            // TODO-sun 测试输出,待删
                            log.debug(" ---- dictCode: " + fieldDictCode);
                            log.debug(" ---- value: " + value);
                            log.debug(" ----- text: " + textValue);
                            log.debug(" ---- dictModels: " + JSON.toJSONString(dictModels));

                            record.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
                        }
                    }
                }

                ((IPage) ((Result) result).getResult()).setRecords(items);
            }

        }
        return result;
    }

改造

判断传递参数的类型,是IPage、List、Map、Object,如果是IPage、List、Map,则把对象中的数据拿出来再挨个转换,改造为新的结果数据返回。

  private Object parseDictText(Object result) {
        if (result instanceof Result) {
            List<Object> list = new LinkedList<>();
            if (((Result) result).getResult() instanceof IPage) {
                //分页
                list = ((IPage) ((Result) result).getResult()).getRecords();
            } else if (((Result) result).getResult() instanceof List) {
                //List集合
                list = (List<Object>) ((Result) result).getResult();
            } else if (((Result) result).getResult() instanceof Map) {
                //map
                Map<Object, Object> map = (Map<Object, Object>) ((Result) result).getResult();
                Map<Object, Object> itemMap = new HashMap<>();
                for (Map.Entry entry : map.entrySet()) {
                    //System.out.println(entry.getKey() + " " + entry.getValue());
                    Map mapRe = new HashMap();
                    if (entry.getValue() instanceof List) {
                        //列表
                        List<Object> listItems = new ArrayList<>();
                        for (Object record : (List) entry.getValue()) {
                            if (checkIsJsonStr(record)) {
                                //字典翻译
                                record = this.dictEscape(record);
                            }
                            listItems.add(record);
                        }
                        itemMap.put(entry.getKey(), listItems);
                    } else if (entry.getValue() instanceof Object) {
                        //单对象
                        Object record = entry.getValue();
                        //判断能否转换成JSON,因为有些结果集返回的是String类型,导致翻译异常,因此判断是否可以转换json
                        if (checkIsJsonStr(record)) {
                            //字典翻译
                            record = this.dictEscape(record);
                        }
                        itemMap.put(entry.getKey(), record);
                    }
                }
                ((Result) result).setResult(itemMap);
            } else {
                //单对象
                Object record = ((Result) result).getResult();
                //判断能否转换成JSON,因为有些结果集返回的是String类型,导致翻译异常,因此判断是否可以转换json
                if (checkIsJsonStr(record)) {
                    //字典翻译
                    record = this.dictEscape(record);
                }
                ((Result) result).setResult(record);
            }

            //列表解析
            if (list != null && list.size() > 0) {
                List<Object> items = new ArrayList<>();
                for (Object record : list) {
                    if (checkIsJsonStr(record)) {
                        //字典翻译
                        record = this.dictEscape(record);
                    }
                    items.add(record);
                }
                if (((Result) result).getResult() instanceof IPage) {
                    ((IPage) ((Result) result).getResult()).setRecords(items);
                } else if (((Result) result).getResult() instanceof List) {
                    ((Result) result).setResult(items);
                }
            }
        }
        return result;
    }

字典翻译方法:

    /**
     * 字典翻译
     *
     * @param record
     * @return
     */
    private JSONObject dictEscape(Object record) {
        ObjectMapper mapper = new ObjectMapper();
        String json = "{}";
        JSONObject item = null;
        try {
            //解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
            json = mapper.writeValueAsString(record);//对象序列化为JSON字符串
        } catch (JsonProcessingException e) {
            log.error("json解析失败" + e.getMessage(), e);
        }
        try {
            item = JSONObject.parseObject(json);
            //update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
            for (Field field : oConvertUtils.getAllFields(record)) {
                //update-end--Author:scott  -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
                if (field.getAnnotation(Dict.class) != null) {
                    String code = field.getAnnotation(Dict.class).dicCode();
                    String text = field.getAnnotation(Dict.class).dicText();
                    String table = field.getAnnotation(Dict.class).dictTable();
                    String key = String.valueOf(item.get(field.getName()));
                    //翻译字典值对应的txt
                    String textValue = key;
                    //非中文时翻译
                    if (!checkCountName(key)) {
                        textValue = translateDictValue(code, text, table, key);
                    }
                    log.debug(" 字典Val : " + textValue);
                    log.debug(" __翻译字典字段__ " + field.getName() + CommonConstant.DICT_TEXT_SUFFIX + ": " + textValue);
                    item.put(field.getName() + CommonConstant.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()))));
                }
            }
        } catch (Exception e) {
            log.info("字典翻译异常:" + e.getMessage(), e);
        }
        return item;
    }

检测是否是中文:

 /**
     * 检测是否是中文
     *
     * @param countName
     * @return
     */
    public static boolean checkCountName(String countName) {
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(countName);
        if (m.find()) {
            return true;
        }
        return false;
    }

检测是否可转换为JSON字符串

/**
     * 检测是否可转换为JSON字符串
     *
     * @param record
     * @return
     */
    public static boolean checkIsJsonStr(Object record) {
        boolean jsonFlag = false;
        try {
            String json = new ObjectMapper().writeValueAsString(record);
            if (json.startsWith("{")) {
                jsonFlag = true;
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return jsonFlag;
    }
相关推荐
小字节,大梦想17 分钟前
【数据结构】详细介绍各种排序算法,包含希尔排序,堆排序,快排,归并,计数排序
c语言·数据结构·c++·算法
Mryan200524 分钟前
OpenJudge | 寻找中位数
开发语言·数据结构·c++·算法·openjudge
阿巴~阿巴~2 小时前
C_深入理解指针(五) —— sizeof和strlen的对比、数组和指针笔试题解析、指针运算笔试题解析
c语言·开发语言·数据结构·算法
酷酷的崽7985 小时前
【数据结构】——原来排序算法搞懂这些就行,轻松拿捏
数据结构·算法·排序算法
北南京海8 小时前
【C++入门(5)】类和对象(初始类、默认成员函数)
开发语言·数据结构·c++
阿拉伯的劳伦斯2928 小时前
LeetCode第一题(梦开始的地方)
数据结构·算法·leetcode
Mr_Xuhhh8 小时前
C语言深度剖析--不定期更新的第六弹
c语言·开发语言·数据结构·算法
paidaxing_s9 小时前
【STL中容器汇总】map、list、vector等详解
开发语言·c++·list
桃酥4039 小时前
算法day22|组合总和 (含剪枝)、40.组合总和II、131.分割回文串
数据结构·c++·算法·leetcode·剪枝
桃酥4039 小时前
算法day21|回溯理论基础、77. 组合(剪枝)、216.组合总和III、17.电话号码的字母组合
java·数据结构·c++·算法·leetcode·剪枝