springboot 字典翻译

  • 一、基于注解和jackson序列化实现字典翻译
  • 二、 基于注解和aop实现字典翻译

本文主要介绍两种在项目中用到的字典翻译方式:

一、基于注解和jackson序列化实现字典翻译

添加字典,指定自定义的序列化类

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside  //让此注解可以被Jackson扫描到
@JsonSerialize(using = DictSerializer.class) //配置处理此注解的序列化处理类
public @interface Dict {/*** 数据code* @return 返回类型: String*/String dicCode();/*** 数据Text* @return 返回类型: String*/String dicText() default "";/*** 数据字典表* @return 返回类型: String*/String dictTable() default "";
}

创建自定义序列化类继承JsonSerialize实现ContextualSerializer,实现返回结果转译:


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.jeeplus.common.utils.RedisUtils;
import com.jeeplus.common.utils.SpringContextHolder;
import com.jeeplus.modules.sys.service.DictTypeService;
import lombok.extern.slf4j.Slf4j;import java.util.*;@Slf4j
public class DictSerializer extends StdSerializer<Object> implements ContextualSerializer {private transient String dicCode;private transient String dicText;private transient String dicTable;private transient static RedisUtils redisUtils;public transient static String prefix = "dict";static {redisUtils = SpringContextHolder.getBean(RedisUtils.class);}protected DictSerializer() {super(Object.class);}@Overridepublic JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty beanProperty) {Dict dict = beanProperty.getAnnotation(Dict.class);return createContextual(dict.dicCode(), dict.dicText(), dict.dictTable());}private JsonSerializer<?> createContextual(String dicCode, String dicText, String dictTable) {DictSerializer serializer = new DictSerializer();serializer.setDicCode(dicCode);serializer.setDicText(dicText);serializer.setDicTable(dictTable);return serializer;}@Overridepublic void serialize(Object value, JsonGenerator gen, SerializerProvider provider) {String dictCode = getDicCode();if (StrUtil.isBlank(dictCode)) {return;}if (Objects.isNull(value) || value.equals("")) {value = "";}try {String cacheKey;if (StrUtil.isNotEmpty(dicTable)) {cacheKey = String.join("::", prefix, String.join("_", dicTable, dictCode, dicText, String.valueOf(value)));} else {cacheKey = String.join("::", prefix, dictCode);}Map<Object, Object> cacheDictMap = redisUtils.hGetAll(cacheKey);String label;if (CollUtil.isEmpty(cacheDictMap)) {Map<String, String> dictMap = translateDictValue(dictCode, dicText, dicTable, String.valueOf(value));redisUtils.hPutAll(cacheKey, dictMap);// 通过数据字典类型和value获取namelabel = dictMap != null ? dictMap.get(value.toString()) : null;} else {// 通过数据字典类型和value获取namelabel = cacheDictMap.get(value.toString()) != null ? cacheDictMap.get(value.toString()).toString() : null;}gen.writeObject(value);// 在需要转换的字段上添加@Dict注解,注明需要引用的code,后端会在返回值中增加filedName_dictText的key,前端只需要取对应的 filedName_dictText 就可以直接使用gen.writeFieldName(gen.getOutputContext().getCurrentName() + "_dictText");gen.writeObject(label);} catch (Exception e) {log.error("错误信息:{}", e.getMessage(), e);}}private Map<String, String> translateDictValue(String code, String text, String table, String value) {if (StrUtil.isBlank(code)) {return null;}Map<String, String> map = new HashMap<>();if (StrUtil.isNotEmpty(table)) {String textValue = SpringContextHolder.getBean(DictTypeService.class).translateDictFromTable(table, text, code, value);map.put(value, textValue);} else {List<Map<String, String>> tmpValue = SpringContextHolder.getBean(DictTypeService.class).translateDict(code);if (CollUtil.isNotEmpty(tmpValue)) {for (Map<String, String> stringMap : tmpValue) {map.put(stringMap.get("value"), stringMap.get("label"));}}}return map;}public String getDicCode() {return dicCode;}public void setDicCode(String dicCode) {this.dicCode = dicCode;}public String getDicText() {return dicText;}public void setDicText(String dicText) {this.dicText = dicText;}public String getDicTable() {return dicTable;}public void setDicTable(String dicTable) {this.dicTable = dicTable;}
}

translateDictValue将查询到的字典保存到map中,因为序列化是需要每个对象都进行序列话操作,如果返回的是集合的话,就会进行很多次序列化操作,此时就需要对相同类型的字典进行缓存。

总结: 相比于使用 aop 切面的方式,使用序列化的方式能更好的处理嵌套对象的字典翻译

二、 基于注解和aop实现字典翻译

添加字典

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Dict {/*** 数据code* @return 返回类型: String*/String dicCode();/*** 数据Text* @return 返回类型: String*/String dicText() default "";/*** 数据字典表* @return 返回类型: String*/String dictTable() default "";
}

定义切面类。具体的实现逻辑根据自己的项目实际情况实现就可以,主要是要用反射去获取类中的字段属性

@Aspect
@Component
@Slf4j
public class DictAspect {/*** 定义切点Pointcut*/@Pointcut("execution(public * com.xxxx.*..*.*Controller.*(..))")public void dictPoint() {}@Around("dictPoint()")public Object doAround(ProceedingJoinPoint pjp) throws Throwable {long time1 = System.currentTimeMillis();Object result = pjp.proceed();long time2 = System.currentTimeMillis();log.debug("获取JSON数据 耗时:" + (time2 - time1) + "ms");long start = System.currentTimeMillis();result = this.parseDictText(result);long end = System.currentTimeMillis();log.debug("注入字典到JSON数据  耗时" + (end - start) + "ms");return result;}private Object parseDictText(Object result) {return result;}/*** 检测返回结果集中是否包含Dict注解** @param records* @return*/private Boolean checkHasDict(List<Object> records) {if (CollectionUtil.isNotEmpty(records)) {for (Field field : getAllFields(records.get(0))) {if (!Objects.isNull(field.getAnnotation(Dict.class))) {return true;}}}return false;}/*** 获取类的所有属性,包括父类** @param object* @return*/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;}
}

springboot 字典翻译相关推荐

  1. SpringBoot字典翻译

    字典注解: import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.la ...

  2. 字典翻译EasyTrans简单使用分享

    前言 最近太忙了,一直按在项目上摩擦,都没有时间写分享了.今天终于市把所有负责的模块都写完了,本次迭代引入了字典翻译,借这个机会顺便分享下. 一.什么是字典翻译 所谓的字典翻译其实简单理解就是一些不常 ...

  3. Element UI 实现字典翻译

    小白记录下element ui的学习过程. 这样的一个页面,需要将所有控件的label名称包括table的表头,都改成可根据字典翻译的 这是原本的写法 首先,需要从数据库中将字典的对象查出来 在页面渲 ...

  4. java 数据字典翻译_BeanUtils——JavaBean相互转换及字典翻译

    翻译JavaBean中带有@CacheFormat的属性/** * 翻译当前类中需要翻译的字典值 * * @param source 待翻译的对象 */ public static  void dat ...

  5. Jeecg-boot字典翻译改造

    一.找到字典切面类(DictAspect) 二.改造方法(parseDictText) 三.修改后的parseDictText方法,支持IPage.List.Object private void p ...

  6. jeecg-boot字典翻译改造(支持实体类详情查询自动翻译)

    找到字典切面类(DictAspect) 改造方法(parseDictText) 支持自动生成的列表接口/单个实体类查询翻译 代码如下: private void parseDictText(Objec ...

  7. java字典初始化_字典翻译注解讲解

    原理 使用拦截器,初始化时加载缓存到,使用时判断注解,根据注解解析缓存类,并用正则表达式,翻译后重写json数据,直到返回结果 使用 系统启动时,初始化查询字典,将字典缓存到redis中格式为 /** ...

  8. python怎么建立字典翻译_如何在python中使用字典将荷兰语翻译成英语

    我正试图翻译我是杰森使用这段代码,但当我使用它时,它什么也不会打印出来,除非我做一个像hello这样的单词,然后它会打印出guten tag,但就是这样.另外,我无法将输入数据转换为小写,以便与字典进 ...

  9. Springboot字典回显

    说明 在前后端分离开发的场景下,后端经常会需要将状态或者类型这样的数据以阿拉伯数字返回,比如1:生效,2:失效:3:发布中等等:以往我们的做法都是前后端沟通好前端通过数字和中文自己对应并显示.后端如果 ...

最新文章

  1. matplotlib 散点图和折线图画在一起_使用matplotlib.pyplot画折线图
  2. “腾讯看点”打响信息流的全面战争
  3. 脉冲多普勒雷达_是人类还是动物? 多普勒脉冲雷达和神经网络的目标分类
  4. 为什么服务端程序都需要先 listen 一下?
  5. 防御CSRF、XSS和SQL注入***
  6. 【Elasticsearch】倒排索引原理
  7. 服务器消息不是按顺序来的,消息队列之 RocketMQ(示例代码)
  8. Leetcode130.被围绕的区域
  9. 纯CSS实现二级下拉导航菜单
  10. json map 转换 android,map和json之间的转换
  11. 入门级CC(Smart3D)照片建模
  12. 网页三剑客8免费下载加序列号
  13. 我在51CTO微职位学PMP_飘过攻略及心得分享
  14. 【信号处理】采样定理的深入浅出
  15. php upload 上传类,发布一个PHP的文件上传类——Uploader
  16. 自监督学习(四)Joint Unsupervised Learning of Deep Representations and Image Clusters
  17. Hibernate(一)
  18. linux内核 4g拨号,openwrt 基于qmi的 3G|4G拨号
  19. php vip卡,vip.php
  20. DPU-PYNQ使用笔记

热门文章

  1. python多维数组排序算法_python 多维数组的排序
  2. Salesforce Admin管理员中文学习教程_如何高效筛选出具有Admin权限的用户!
  3. 硬盘读写资料,感觉真是真是专业,长见识呀。不同反响。一定要好好记得,这样有事情,就可以讲了。这些东东才有说服力,也专业。
  4. Spine学习八 - 幻影特效
  5. 佛道相争---阐述了之间的区别
  6. html总结常见问题
  7. ORACLE数据库中使用JAVA源实现SM3签名算法
  8. springboot教室图书馆座位预约小程序毕业设计毕设作品开题报告开题答辩PPT
  9. python linux 串口,python 实现linux串口收发数据源码
  10. 20计算机考研,推荐哪些学校?