彻底解决JS处理Long类型精度丢失问题(二)

当你的序列化方式采用的FastJson时,该如何处理这种类型转换问题呢?一模一样的套路…

SpringMVC 使用FastJson序列化方式

1.增加类型转换类:

public class FastJsonConfigExt  extends FastJsonConfig {
    public FastJsonConfigExt(){
        super();
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
        serializeConfig.put(Long.class,ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE,ToStringSerializer.instance);
        this.setSerializeConfig(serializeConfig);
    }
}

2.spring mvc 配置文件增加:

    <!--解决fastJson 转换long型,精度丢失的问题-->
    <bean id="fastJsonConfigExt" class="com.ymm.web.configuration.FastJsonConfigExt"/>

    <!-- 解决@ResponseBody注解直接返回对象并转换成JSON时出现406问题,同时解决了返回String类型乱码的问题 -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="fastJsonConfig" ref="fastJsonConfigExt" />
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json; charset=UTF-8</value>
                        <value>application/x-www-form-urlencoded; charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
                <property name="features">
                   <list>
                       <!-- null String也要输出 -->
                       <value>WriteMapNullValue</value>
                       <!-- 输出key时是否使用双引号 -->
                       <value>QuoteFieldNames</value>
                       <!-- 字符类型字段如果为null,输出为"",而非null -->
                       <value>WriteNullStringAsEmpty</value>
                   </list>
               </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

执行完以上两个步骤,便可以将Long类型转为String类型,然后在序列化为JSON数据。但是存在一个问题:fastjson不支持基础类型如long double等的转换,仅支持包装类型。如何解决呢,请看下文。

使用FastJson自定义过滤器,过滤指定字段

1.通过实现FastJson的ValueFilter接口,增加自定义类型转换器。

public class FastJsonFilterExt implements ValueFilter {
    @Override
    public Object process(Object object, String name, Object value) {
        String userIdStr = "";
        switch (name.toLowerCase()) {
            case "userid":
            case "orderid":{
                if (value != null) {
                    userIdStr = String.valueOf(value);
                    return userIdStr;
                }
            }
        }
        return value;
    }
}

2.xml追加配置:

 <!--解决fastJson 转换long型,精度丢失的问题-->
    <bean id="fastJsonFilterExt" class="com.ymm.web.configuration.FastJsonFilterExt"/>

    <!-- 解决@ResponseBody注解直接返回对象并转换成JSON时出现406问题,同时解决了返回String类型乱码的问题 -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json; charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
               <property name="features">
                   <list>
                       <!-- null String也要输出 -->
                       <value>WriteMapNullValue</value>
                       <!-- 输出key时是否使用双引号 -->
                       <value>QuoteFieldNames</value>
                       <!-- 字符类型字段如果为null,输出为"",而非null -->
                       <value>WriteNullStringAsEmpty</value>
                   </list>
               </property>
                <property name="filters">
                    <list>
                        <ref bean="fastJsonFilterExt"></ref>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

上面通过指定字段名称的方式进行过滤转换类型,解决了long等基础数据类型不能转换为String的问题,同时指定字段进行类型转换避免了所有Long类型字段都被转换的尴尬。

使用自定义注解,过滤指定字段

当然也可以通过增加自定义注解方式,在实体属性上面增加自定义注解,指定要转换的字段,在转换器中判断是否包含注解。

1.增加自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface FieldToString {
    public  String  value()  default "true";
}

2.增加转换器:

    public class BeanPropertyFilter 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(FieldToString.class).value().equals("true");
                if (flag == true && value != null) {
                    // 将其他类型转换成String类型
                    value = String.valueOf(value);
                }
            } catch (NoSuchFieldException e) {
                return value;
            } catch (Exception e) {
                return value;
            }
            return value;
        }
    }

3.使用方式

直接在要转换的字段上增加@FieldToString注解即可。


参考:
https://www.jianshu.com/p/8d8152725114?from=singlemessage

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值