当前位置: 首页 > news >正文

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类的@JsonFormatjson = 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) {//mapMap<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类型,导致翻译异常,因此判断是否可以转换jsonif (checkIsJsonStr(record)) {//字典翻译record = this.dictEscape(record);}itemMap.put(entry.getKey(), record);}}((Result) result).setResult(itemMap);} else {//单对象Object record = ((Result) result).getResult();//判断能否转换成JSON,因为有些结果集返回的是String类型,导致翻译异常,因此判断是否可以转换jsonif (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类的@JsonFormatjson = 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()));//翻译字典值对应的txtString 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;}

相关文章:

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

改造的是DictAspect类&#xff1a; 原来使用的 parseDictText(Object result)方法&#xff0c;针对返回对象为Result 的IPage的分页列表数据进行动态字典注入&#xff0c;当单个对象查询&#xff0c;列表查询&#xff0c;或者多个数据放到Map中时&#xff0c;就不会自动转化&am…...

DVWA DOM Based Cross Site Scripting (DOM型 XSS)

DVWA DOM Based Cross Site Scripting (DOM型 XSS) 文章目录 DVWA DOM Based Cross Site Scripting (DOM型 XSS)XSS跨站原理DOM型 LowMediumHighImpossible XSS跨站原理 当应用程序发送给浏览器的页面中包含用户提交的数据&#xff0c;但没有经过适当验证或转义时&#xff0c;就…...

LinkedList集合及迭代器的源码分析

一.介绍: 二.LinkedList集合特有的API: 三.迭代器的源码分析: package com.itheima.a03myarraylist;import java.util.ArrayList; import java.util.Iterator;public class A01_ArrayListDemo1 {public static void main(String[] args) {ArrayList<String> listnew Arr…...

Go调度器

线程数过多,意味着操作系统会不断地切换线程,频繁的上下文切换就成了性能瓶颈.Go提供一种机制 可以在线程中自己实现调度,上下文切换更轻量,从而达到线程数少,而并发数并不少的效果,而线程中调度的就是Goroutine 调度器主要概念: 1.G:即Go协程,每个go关键字都会创建一个协程…...

当node节点kubectl 命令无法连接到 Kubernetes API 服务器

1.问题 当node节点当node节点kubectl 命令无法连接到 Kubernetes API 服务器 [rootnode1 ~]# kubectl get nodes The connection to the server localhost:8080 was refused - did you specify the right host or port?2. 确认 kubeconfig 文件 确保节点上有有效的 kubeco…...

直接通过类CURL方式,与GRPC方法交互的命令行工具

大家好&#xff0c;今天给大家分享的是一个命令行工具grpcurl&#xff0c;它能够直接与 gRPC 服务进行交互。 项目介绍 您可以把grpcurl想象成是 curl 的 gRPC 版本&#xff0c;但是功能更加强大。 由于 gRPC 服务之间的通信使用的是 Protocol Buffers (Protobuf) 格式的二进…...

Hive3:数据的加载与导出

一、加载数据 在创建表之后&#xff0c;表中没有数据&#xff0c;我们不可能insert存入数据。 而是&#xff0c;通过数据加载&#xff0c;将HDFS中的数据关联到Hive表中。 建表 CREATE TABLE myhive.test_load(dt string comment 时间&#xff08;时分秒&#xff09;, user_…...

React事件绑定的方式有哪些?区别?

React 中事件绑定的方式主要有以下几种&#xff1a; 直接在 JSX 中绑定事件&#xff1a; <button onClick{handleClick}>Click me</button> 这是最常见和推荐的方式。事件名&#xff08;如 onClick&#xff09;作为 JSX 的属性&#xff0c;值为一个函数&#xff0c…...

ibis:极具潜力的Python数据分析新框架

今天要给大家介绍的Python框架叫做ibis&#xff0c;没错&#xff0c;跟著名连锁酒店宜必思同名&#xff0c;其作者是创造了pandas、Arrow等著名框架的Wes McKinney。 ibis的核心理念是用同一套数据框操作API&#xff0c;统一操纵各种主流的数据运算框架&#xff0c;使得用户可以…...

SQL Zoo 8+.NSS Tutorial

以下数据来自SQL Zoo 1.at Edinburgh Napier University&#xff0c;studying (8) Computer Science&#xff0c;Show the the percentage who STRONGLY AGREE.&#xff08;在爱丁堡纳皮尔大学&#xff0c;学习“计算机科学”&#xff0c;显示STRONGLY AGREE的百分比&#xff0…...

conda pack迁移环境

文章目录 下载conda pack打包已有环境还原环境 因为有的服务器没有网络&#xff0c;如果想要安装自己的虚拟环境&#xff0c;就需要在有网络的服务器安装好环境后迁移到没有网络的服务器。conda-pack是一个命令行工具&#xff0c;用于打包 conda 环境&#xff0c;pip inatall和…...

UML建模案例分析-活动图商业建模

概述 活动图主要用来描述如何完成工作以及做什么工作。可以用活动图来描述操作、类或 用例&#xff0c;但是它们只能显示工作流。可以用活动图来进行商业建模&#xff0c;在模型中&#xff0c;工作、工 人、组织、对象被显示。 案例 在商业建模时&#xff0c;下列方面是模型要…...

C++标准模板(STL)- 低层内存管理 - 解分配函数 (operator delete, operator delete[])

低层内存管理 new 表达式是创建拥有动态存储期对象或对象数组的仅有方式&#xff0c;即它们拥有不受制于创建所它们在的作用域的生存期。 new 表达式通过调用分配函数获得存储。 delete 表达式销毁最终导出对象或通过 new 表达式创造的数组&#xff0c;然后调用解分配函数。默认…...

LeetCode 热题 HOT 100 (025/100)【宇宙最简单版】

【二叉树】No. 0124 二叉树中的最大路径和 【困难】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你…...

【mysql 第三篇章】一条 update语句是怎么持久化到磁盘上的?

首先看一下这个 SQL 语句你会不会写? 下面是说明执行这个 SQL 语句&#xff0c;数据库底层做了什么操作。 update users set namexxx where id10;在引擎要执行更新语句的时候&#xff0c;比如更新 id10 这行数据时&#xff0c;他会先查看数据在缓冲池中是否存在&#xff0c;如…...

深入探索大模型:从基础到实践,开启AI之旅

摘要&#xff1a; 在人工智能领域&#xff0c;大模型技术正成为推动创新和进步的关键力量。对于初学者而言&#xff0c;掌握大模型的基本概念、理论和技术是至关重要的。 本文将为你提供一个全面的学习路线&#xff0c;帮助你从基础知识出发&#xff0c;逐步深入到大模型的实践…...

题解:力扣1567 - 返回乘积为正数的最长子数组

问题描述 给定一个整数数组 nums&#xff0c;找出乘积为正数的最长子数组的长度。这里的子数组定义为连续元素的序列&#xff0c;乘积为正数指子数组中正数的个数必须大于负数的个数。 解题思路 为了解决这个问题&#xff0c;我们可以使用两个数组 f 和 g 分别表示以当前位置…...

009 | 上证50ETF基金数据分析及预测

项目背景 中国股市的发展历程坎坷,从最初的茫然到现在的逐步成熟,股市已经成为中国经济发展的重要标志之一。然而,当前中国股市仍存在投机行为过度和定价机制不完善等问题。为更好地理解和预测股市走势,本项目聚焦于上证50ETF基金的历史数据分析和未来走势预测。 项目目标…...

Wakanda: 1靶场复现【附代码】(权限提升)

靶机下载地址&#xff1a; wakanda: 1 ~ VulnHubwakanda: 1, made by xMagass. Download & walkthrough links are available.https://www.vulnhub.com/entry/wakanda-1,251/#download 1. 主机发现端口扫描目录扫描敏感信息获取 1.1. 主机发现 nmap -sn 192.168.7.0/24…...

内核函数调试

要进入 bind 函数的内部进行调试&#xff0c;实际上是不能直接在用户空间代码中进入内核内部的 bind 实现&#xff0c;因为 bind 是一个系统调用&#xff0c;它由内核处理。尽管如此&#xff0c;你可以通过以下几种方法来间接调试 bind 函数并理解它的行为&#xff1a; 1. 使用…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...