• 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 items = new ArrayList<>();
    
                    //step.1 筛选出加了 Dict 注解的字段列表
                    List dictFieldList = new ArrayList<>();
                    // 字典数据列表, key = 字典code,value=数据列表
                    Map> dataListMap = new HashMap<>(5);
                    //取出结果集
                    List 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 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> 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 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 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) ((Result) result).getResult();
                } else if (((Result) result).getResult() instanceof Map) {
                    //map
                    Map map = (Map) ((Result) result).getResult();
                    Map 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 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 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;
        }
    
  • 相关阅读:
    Linux 调试 (objdump/strace/strings)
    2022世界杯La‘eeb肖像,python海龟实现啦
    Java工厂模式之总有你想不到的知识
    C语言学习系列-->一篇带你看懂内存函数
    【 Tkinter界面-练习05】 event和bind
    Modality to Modality Translation
    Adobe家里的“3D“建模工 | Dimension
    【VIO】练习1 IMU标定
    Leetcode算法入门与数组丨3. 数组基础
    完整的 HTTPS 的通信
  • 原文地址:https://blog.csdn.net/weixin_44934104/article/details/140948027