自定义注解来进行类型转换

文章讲述了在处理金额和面积数据时,为避免精度丢失,采用Double到Long的转换,以及在前后端交互中使用自定义注解和FastJson的ValueFilter进行数据类型转换的方法。通过创建DoubleCovertToLong和LongCovertToDouble注解,以及对应的转换过滤器,实现了在保存和返回数据时的自动转换。
摘要由CSDN通过智能技术生成

工作中有一个需求,在填写一些金额和面积数据时,要求新增时前端传double类型,后端将其乘以10000并转换为Long类型,存入数据库

返回详情时后端又将其除以10000并转换为double类型返回给前端

以此来达到精度不丢失的情况(这种情况我以前一直用的是BigDecimal,觉得没啥问题,组长却告诉我会有精度丢失,有知道原因的兄弟能帮我解答下吗)

一开始,我是打算直接在后台get字段数据转换即可

但是后面数据量太庞大了,造成代码很多,就想着写个自定义注解来解决.在网上看了一下,最后实现了

上图这是原来的写法,可以看到,如果数据量再大一些,就只有继续往后添加,太麻烦了


现在我们来写自定义注解

当初我是看的这篇文章(附原文地址:fastJson 自定义注解和过滤器完成自定义序列化 - 简书)

整个创建步骤:

1.创建注解,在这里注解只作为一个标识

2.准备两个自定义类(A类,B类),字段名相同,数据类型不同(将传来的A类中的字段转换类型,最后再转成B类)

3.通过阿里的JSON中toJSONStirng()方法来进行数据转换,传一个转换Filter

4.自定义转换逻辑,创建类去实现ValueFilter接口,重写process()方法

5.将需要转换的对象通过toJSONStirng()方法转换为String字符串,再将字符串转为想要的类

fastjson支持6种SerializeFilter,用于不同场景的定制序列化。

PropertyPreFilter 根据PropertyName判断是否序列化 
PropertyFilter 根据PropertyName和PropertyValue来判断是否序列化 
NameFilter 修改Key,如果需要修改Key,process返回值则可 
ValueFilter 修改Value 
BeforeFilter 序列化时在最前添加内容 
AfterFilter 序列化时在最后添加内容

一. 创建注解

/**
 * double类型转为Long类型
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DoubleCovertToLong {

    public  String  value()  default "true";

}

 

/**
 * Long类型转为double类型
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface LongCovertToDouble {

    public  String  value()  default "true";

}

二. 准备A类B类,字段名相同,数据类型不同

 接收前端传的Double类型

A类

    /** 建设规模(公顷) */
    @DoubleCovertToLong
    private Double constrArea;

    /** 预计投资金额 */
    @DoubleCovertToLong
    private Double investMoney;

后端入数据库的Long类型 

B类

    /** 建设规模(公顷) */
    @LongCovertToDouble
    private Long constrArea;

    /** 预计投资金额 */
    @LongCovertToDouble
    private Long investMoney;

三. 自定义类实现ValueFilter接口,重写process方法,实现转换逻辑

/**
 * 转换类-Long
 */
public class BeanPropertyToLangFilter implements ValueFilter {
    private Field field = null;


    @Override
    public Object process(Object obj, String name, Object value) {
        Boolean flag = false;
        try {
            field = obj.getClass().getDeclaredField(name);
            // 获取注解
            flag = field.getAnnotation(DoubleCovertToLong.class).value().equals("true");
            if (flag == true && value != null) {
                // 这里 其他类型转换成Long类型
//                value += "";
                value = Double.valueOf((Double) value*10000).longValue();
            }
        } catch (NoSuchFieldException e) {
            return value;
        } catch (Exception e) {
            return value;
        }
        return value;
    }
}

 

/**
 * 转换类-Double
 */
public class BeanPropertyToDoubleFilter implements ValueFilter {
    private Field field = null;


    @Override
    public Object process(Object obj, String name, Object value) {
        Boolean flag = false;
        try {
            field = obj.getClass().getDeclaredField(name);
            // 获取注解
            flag = field.getAnnotation(LongCovertToDouble.class).value().equals("true");
            if (flag == true && value != null) {
                // 这里 其他类型转换成Double类型
                value = Double.parseDouble(value.toString())/10000;
            }
        } catch (NoSuchFieldException e) {
            return value;
        } catch (Exception e) {
            return value;
        }
        return value;
    }
}

四. 具体实现

新增,Double->Long 

try {
            // 创建转换工具类对象
            BeanPropertyToLangFilter beanPropertyToLangFilter =new BeanPropertyToLangFilter();
            // 转换
            String jsonString = JSON.toJSONString(a, beanPropertyToLangFilter);
            b = JSON.parseObject(jsonString, b.getClass());

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

详情,Long-> Double

try {
            // 创建转换工具类对象
            BeanPropertyToDoubleFilter beanPropertyToDoubleFilter =new BeanPropertyToDoubleFilter();
            String jsonString = JSON.toJSONString(b, beanPropertyToDoubleFilter);
            // 转换
            a = JSON.parseObject(jsonString,a.getClass());
}catch(Exception e){
    throw new RuntimeException(e);
}

注意: 大家在运行时可以debug调试,在转为json字符串时,实际上是发现该对象所有字段上包含

@DoubleCovertToLong注解的或者包含@LongCovertToDouble注解的字段

然后如果你还要进行其他的重新赋值操作,建议先转换完类型之后再做其他操作,不然会有数据丢失的情况,具体的大家可以调试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值