翻译JavaBean中带有@CacheFormat的属性/**

* 翻译当前类中需要翻译的字典值

*

* @param source 待翻译的对象

*/

public static  void dataFormatter(T source) {     //判断原对象是否为null

Assert.notNull(source, "待翻译的原对象不能为null");     //获取所有属性并翻译字典

Field[] declaredFields = source.getClass().getDeclaredFields();     //翻译字典:找出所有含有@CacheFormatter的属性

Stream fieldStream = Arrays.stream(declaredFields)             //排除没有注解@CacheFormatter的字段

.filter(field -> field.isAnnotationPresent(CacheFormat.class));     //翻译

doFormatter(fieldStream, source, source.getClass());

}

翻译List/**

* 翻译当前集合类中需要翻译的字典值

*

* @param sources 待翻译的集合对象

*/

public static  void dataFormatter(List sources) {     //当翻译的集合为空时,返回空的集合

if (sources == null || sources.isEmpty()) {         return;

}

Class targetClass = sources.get(0).getClass();     //获取所有属性并翻译字典

Field[] declaredFields = targetClass.getDeclaredFields();     //翻译字典:找出所有含有@CacheFormat的属性集合

List formatterFields = Arrays.stream(declaredFields)             //排除没有注解@CacheFormat的字段

.filter(field -> field.isAnnotationPresent(CacheFormat.class))

.collect(Collectors.toList());     //循环列表(并行操作)

sources.parallelStream().forEach(target -> {         //翻译

doFormatter(formatterFields.stream(), target, targetClass);

});

}

Entity 与DTO互转/**

* 把原对象转换成目标类的对象,并翻译目标类的属性字典

* 只针对目标类没有范型或者范型与原对象一样

* @param source      原对象

* @param targetClass 目标类

* @return 目标对象

*/public static  T dataConvert(Object source, Class targetClass) {

Assert.isTrue(source != null && targetClass != null, "原对象或目标class不能为null");

T target = BeanUtils.instantiateClass(targetClass);    //把目标对象的属性设置成原对象中对应的属性

BeanUtils.copyProperties(source, target);

dataFormatter(target);    return target;

}/**

* 实体属性互转

*

* @param source 原对象

* @param target 目标对象

* @return 目标对象

*/public static  T dataObjConvert(Object source, T target) {

Assert.isTrue(source != null && target != null, "待转换的原对象或目标对象不能为null");    //转换

BeanUtils.copyProperties(source, target);    //翻译

dataFormatter(target);    return target;

}

List/**

* 批量把原对象转换成目标对象,并翻译目标对象的属性字典

* 如果想返回指定类型的集合即List的子类,参考{@link  HyBeanUtils#dataConverts2}

*

* @param sources     原对象集合

* @param targetClass 目标对象的类

* @return 返回转换后的目标集合

*/public static  List dataConverts(List sources, Class targetClass) {

Assert.notNull(targetClass, "转换的目标Class不能为null");    //当翻译的集合为空时,返回空的集合

if (sources == null || sources.isEmpty()) {

List targetList = new ArrayList<>();        return targetList;

}    //获取原集合的类型

Class extends List> aClass = sources.getClass();    //目标集合

List targetList = BeanUtils.instantiateClass(aClass);    //把目标对象的属性设置成原对象中对应的属性(并行操作)

sources.parallelStream().forEach(item -> {

T target = BeanUtils.instantiateClass(targetClass);

BeanUtils.copyProperties(item, target);

targetList.add(target);

});    //翻译字典

dataFormatter(targetList);    return targetList;

}

这个是List转换的升级版 T/**

* 返回指定类型的方法,这里的类型必须是List的子类

* 批量把原对象转换成目标对象,并翻译目标对象的属性字典,

*

* @param sources     原对象集合

* @param targetClass 目标对象的类

* @param returnType  返回值类型

* @return 返回转换后的目标集合

*/public static > R dataConverts2(List sources, Class targetClass, Class returnType) {

Assert.notNull(targetClass, "转换的目标Class不能为null");

Assert.notNull(returnType, "返回值类型Class不能为null");    //当翻译的集合为空时,返回空的集合

if (sources == null || sources.isEmpty()) {        return null;

}    //目标集合

R targetList = BeanUtils.instantiateClass(returnType);    //把目标对象的属性设置成原对象中对应的属性(并行操作)

sources.parallelStream().forEach(item -> {

T target = BeanUtils.instantiateClass(targetClass);

BeanUtils.copyProperties(item, target);

targetList.add(target);

});    //翻译字典

dataFormatter(targetList);    return targetList;

}

上述所用到的公共方法/**

* 对目标类需要翻译的字段进行翻译

*

* @param stream

* @param target      目标对象

* @param targetClass 目标对象类

*/private static  void doFormatter(Stream stream, Object target, Class targetClass) {    //排除目标对象中字段值为null的字段

stream.filter(field -> {

PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(targetClass, field.getName());        Object invoke = null;        try {

invoke = propertyDescriptor.getReadMethod().invoke(target, new Object[]{});

} catch (IllegalAccessException e) {

logger.warn("待翻译的字段的get是无法访问的", e);

} catch (InvocationTargetException e) {

logger.warn("调用待翻译的字段的get方法时报错", e);

} catch (Exception e) {

logger.warn("确保属性有get,set方法", e);

}        return invoke != null;        //遍历需要翻译的字段

}).forEach(field -> {

CacheFormat annotation = field.getAnnotation(CacheFormat.class);        //缓存系统编号,如果不指定则默认为当前系统编号

String systemCode = "system_code";        if (StringUtils.isNotBlank(annotation.systemCode())) {

systemCode = annotation.systemCode();

}        //缓存key,如果不指定,则默认为字段名称

String key = annotation.key();        if (StringUtils.isBlank(key)) {

key = field.getName();

}        //判断注解@CacheFormatter是否指定把字典翻译到另一个字段上

String formatterField = annotation.destination();        if (StringUtils.isBlank(formatterField)) {            //当注解中不指定其他字段时,默认翻译到加注解的属性上

formatterField = field.getName();

}        try {

PropertyDescriptor orginPropertyDescriptor = BeanUtils.getPropertyDescriptor(targetClass, field.getName());            Object value = orginPropertyDescriptor.getReadMethod().invoke(target, new Object[]{});            //设置目标字段值

PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(targetClass, formatterField);            //取缓存

String cacheValue = RedisUtils.hget(systemCode +":valueset:" + key, value + "");            //如果数据字典中查询不到,则取业务缓存中取

if (StringUtils.isBlank(cacheValue)) {

cacheValue = RedisUtils.hget(systemCode + ":valueset:" + key, value + "");

}

Assert.hasLength(cacheValue, "在缓存" + key + "中没有找到" + value + "对应的缓存");            //设置缓存值到属性字段中

propertyDescriptor.getWriteMethod().invoke(target, cacheValue);

} catch (IllegalAccessException e) {

logger.warn("待翻译的字段的set是无法访问的", e);

} catch (InvocationTargetException e) {

logger.warn("调用待翻译的字段的set方法时报错", e);

} catch (Exception e) {

e.printStackTrace();

logger.warn("调用待翻译的字段的set方法时报错,推测类型不匹配", e);

}

});

}

注解 CacheFormat@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

@Documentedpublic @interface CacheFormat {  /**

*  缓存key

* @return

*/

String key();  /**

* 指定翻译值存放字段, 例如:userType的翻译结果放到userTypeName上

* @return

*/

String destination() default "";  /**

* 系统编号

* @return

*/

String systemCode() default "";

java 数据字典翻译_BeanUtils——JavaBean相互转换及字典翻译相关推荐

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

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

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

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

  3. springboot 字典翻译

    springboot 字典翻译 一.基于注解和jackson序列化实现字典翻译 二. 基于注解和aop实现字典翻译 本文主要介绍两种在项目中用到的字典翻译方式: 一.基于注解和jackson序列化实现 ...

  4. XML与JavaBean相互转换工具

    XML与JavaBean相互转换工具 import com.thoughtworks.xstream.XStream; import java.util.Map; import java.util.I ...

  5. Jeecg-boot字典翻译改造

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

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

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

  7. java 中 image 和 byte[] 相互转换

    转载自  java 中 image 和 byte[] 相互转换 只需要一个存储了图片信息的二进制串(byte[]) 然后,这样: InputStream buffin = new ByteArrayI ...

  8. Gson案例:Java对象与JSON字符串相互转换

    Gson案例:Java对象与JSON字符串相互转换 一.Gson概述 Gson是一个Java类库,可将Java对象转换为相应的JSON形式,也可以将JSON字符串转换为对应的Java对象.Gson是一 ...

  9. Java 8 字符串和时间相互转换

    Java 8 字符串和时间相互转换 1. 常见日期转换符号说明 符号 说明 备注 y 年 Y 本周所在的年 如果日期所在的周跨年了,年份就会是第二年的,需要注意 M 月(month-of-year) ...

最新文章

  1. 信息安全评论员18期
  2. 分布式版本控制系统Git——使用GitStack+TortoiseGit 图形界面搭建Git环境(服务器端及客户端)(转)...
  3. 406(浏览器接收的响应类型和服务器返回的响应类型不匹配)
  4. Java ClassLoader getResources()方法与示例
  5. 看看webpack打包优化
  6. docker搭建upload-labs
  7. win10外放与耳机不能够自动切换没有声音的问题 声卡问题
  8. Linux SD卡驱动开发
  9. python设置计算题_python tkinter做的生成计算题的GUI
  10. P3403 跳楼机 同余最短路
  11. PC端微信聊天记录备份文件在哪儿?
  12. 不同安卓模拟器连接appium的端口
  13. 戴尔dell工作站5820,通电后电源指示灯白灯长亮-待更新
  14. 夜曲 文/江湖一劍客
  15. magicbookpro做php开发,荣耀MagicBook Pro测评:全面屏专业生产力工具
  16. 【密码学】费马小定理素性检测(C++代码实现)
  17. CPython是什么?PyPy是什么?Python和这两个东西有什么关系
  18. 怎样将几个pdf文件合成一个?
  19. @[TOC](CDN防御与高防服务器防御的区别
  20. word 2010中设置默认粘贴为 只保留文本粘贴【visio也适用于快捷键方式】

热门文章

  1. C语言 查询ASCII码
  2. C语言【程序48】题目:八进制转换为十进制、二进制转换为十进制、十进制转换为二进制 、十进制转换为八进制、十六进制转换为十进制、十进制转换为十六进制
  3. pyhton (for in if)用法
  4. 整理:C#中Expression表达式的妙用
  5. doFilter不生效的原因
  6. MAC 添加quickgame 全局变量。
  7. TableLayout中collapseColumns,stretchColumns的介绍
  8. php获取客户端IP地址的几种方法(转)
  9. 北京市高等教育英语听力计算机考试,北京市2021年普通高考第一次英语听力机考开考_学历教育网...
  10. idea多个项目合并一个窗口