BeanUtils——JavaBean相互杏彩平台带保险理赔仓转换及字典翻译

在升级公司架构过程中杏彩平台带保险理赔仓(www.1159880099.com )QQ1159880099,发现有大量Entity与DTO相互转换的问题,并且其中还伴随DTO中的数据字典翻译,所以特意写个工具类,主要利用spring提供的BeanUtils工具类,用redis翻译字典
其中功能包括:

翻译JavaBean中带有@CacheFormat的属性

/**

/**

  • 把原对象转换成目标类的对象,并翻译目标类的属性字典
  • 只针对目标类没有范型或者范型与原对象一样
  • @param source 原对象
  • @param targetClass 目标类
  • @return 目标对象
    */
    public static <T> T dataConvert(Object source, Class<T> 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> 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 <T, E> List<T> dataConverts(List<E> sources, Class<T> targetClass) {

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

    //当翻译的集合为空时,返回空的集合
    if (sources == null || sources.isEmpty()) {
    List<T> targetList = new ArrayList<>();
    return targetList;
    }
    //获取原集合的类型
    Class<? extends List> aClass = sources.getClass();
    //目标集合
    List<T> 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 <T, E, R extends List<T>> R dataConverts2(List<E> sources, Class<T> targetClass, Class<R> 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 <T> void doFormatter(Stream<Field> stream, Object target, Class<T> 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)br/>@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CacheFormat {

/**

  • 缓存key
  • @return
    */
    String key();

    /**

  • 指定翻译值存放字段, 例如:userType的翻译结果放到userTypeName上
  • @return
    */
    String destination() default "";

    /**

  • 系统编号
  • @return
    */
    String systemCode() default "";
    注意:该翻译只关注第一层即当前对象的属性,并不会递归翻译

比如:当前类有一个属性为对象实例,该对象也有被@CacheFormat注解的属性

这时该工具类不会去翻译这个属性中的属性,需要开发者先用当前工具类转换该属性

然后再设置到目标类中

BeanUtils——JavaBean相互杏彩平台带保险理赔仓转换及字典翻译

原文地址:http://blog.51cto.com/13890914/2151248

时间: 2024-10-17 10:50:16

BeanUtils——JavaBean相互杏彩平台带保险理赔仓转换及字典翻译的相关文章

win10 windows许可证杏彩平台搭建即将过期的解决办法

出现这个错误是因为杏彩平台搭建安装论坛:haozbbs.com Q1446595067 的版本不是正版系统,每隔一段时间需要激活这次激活也费了一些时间,记录如下希望能对大家有所帮助 (1)首先可以查看自己的许可什么什么时候会过期windows+R调出命令运行窗口,输入slmgr.vbs -xpr这里写图片描述(2)用工具进行激活MicroKMS神龙版链接:https://pan.baidu.com/s/1bwrKMK_EfA-AnJKdPtaplA 密码:kv39这里写图片描述点击划线进行激活,

Python中 sys.argv[]的杏彩平台出租用法简明解释

因为是看书杏彩平台出租haozbbs.comQ1446595067 自学的python,开始后不久就遇到了这个引入的模块函数,且一直在IDLE上编辑了后运行,试图从结果发现它的用途,然而结果一直都是没结果,也在网上查了许多,但发现这个问题的比较详细的解释只有一个版本,大部分都是转裁和复制的.给的都是简明python教程上那个一长串代码的例子,说看了就明白了,可我看得晕头转向的还是没真正明白,只知道"sys.argv[0]表示代码本身文件路径"这点,其实还是不明其意.后来经过大量努力,多

杏彩平台出租mysql存储过程之遍历多表记录后插入第三方表中

自从学过存储过程后杏彩平台出租(www.1159880099.com )QQ1159880099,就再也没有碰过存储过程,这是毕业后写的第一个存储过程. 因为项目里设备的种类比较多,分别存在不同的数据表中,java中对应不同的java bean对象,想要统一管理有点困难.最近正好要开发一个功能模块,就是需要统一对设备进行处理,想着为了以后都能方便的统一处理各种设备,就从现在开始设计一套方案管理起这些项目吧. 如何统一管理呢? 如果从项目一开始设计的时候就能考虑到项目会发展成今天这样,当初就应该抽

日本励志短片《人生各自精彩杏彩平台出租》

最近小朋友在游泳杏彩平台出租 下载地址 http://hxforum.com/thread-397-1-1.html QQ2952777280[话仙源码论坛]hxforum.com[木瓜源码论坛]papayabbs.com馆学游泳,给他报名的初衷是能够在炎热地环境中继续锻炼一下身体. 可是作为家长的我,在观看了几场游泳训练后,总觉得孩子不够认真和努力--, 接连的"没有追赶精神","没有认真听教练的话","旁边班的小朋友为什么都很熟练了",&qu

Quartz实现JAVA定时杏彩平台出租任务的动态配置

先说点无关杏彩平台出租QQ2952777280[话仙源码论坛]hxforum.com[木瓜源码论坛]papayabbs.com 本文的问题,这段时间特别的不爽,可能有些同学也遇到过.其实也可以说是小事一桩,但感觉也是不容忽视的.我刚毕业时的公司,每个人每次提交代码都有着严格的规范,像table和space的缩进都有严格的要求,可以说你不遵守开发规范就相当于线上bug问题,还是比较严重的.现在发现外面的公司真的是没那么重视这个不重要却又特别重要的问题啊,啊啊啊啊啊啊!!! 什么是动态配置定时任务?

内核中ARP请求的回复控制与杏彩平台出租

ARP收到request请求之后,杏彩平台出租(企 娥:217 1793 408)首先通过路由查询确定目的IP为一个本地地址类型(RTN_LOCAL)后,是否回复arp请求,还取决于两个判断:arp_ignore与arp_filter.可通过sysctl或者proc文件系统查看二者的值,如下所有配置值都为0: $ sudo sysctl -a | grep -w arp_ignorenet.ipv4.conf.all.arp_ignore = 0net.ipv4.conf.default.arp

linux文本处理杏彩平台出租工具之grep与正则表达式语法

Grep介绍Linux 文本处理三剑客之一,文件过滤工具(另外两剑客为sed:文本编辑工具,awk:文本报告生成器) 拥有着,根据用户指定的"模式"对目标文本逐行进行匹配检查:打印匹配到的行的功能. 使用Grep除了正常的字符使用之外 还可以运用正则表达式字符. Grep的重要命令选项 --color=auto 关键字高亮显示(centos7默认) *-v 关键字 显示不包含关关键字的行,取反 *-i 关键字 忽略关键字的大小写 -n 显示的结果每行前增加行号 -c 仅显示找出的结果的

杏彩平台搭建与await在forEach不起作用解决

一.前言前两天在项目中用 杏彩平台搭建[q-21528-76294] 网址diguaym.com for遍历的时候遇到了一个坑,花了一天的时间解决.这里就记一下. 二.问题首先引一个很简单题目:给一个数组,每隔1s打印出来.这里我把我一开始在项目中的代码贴出来.(当然这里完全和业务无关的) const _ = require('lodash'); const echo = async (i) => {setTimeout(() => {console.log('i===>', i);},

原版乐彩源码分享,最新php+mysql时时平台带开奖器和数据库

原版乐彩源码分享,最新php+mysql时时平台带开奖器和数据库,给有需要的朋友.<ignore_js_op> <ignore_js_op>   本人提供一站式服务:联系QQ:2 3 6 0 2 4 8666(私聊)