fastjson将Long类型转换成String类型,解决前后端交互,Java序列化JSON丢失精度问题的方法

后端把Long类型的数据序列化成JSON后传给前端,前端可能会出现精度丢失的情况。

例如:201511200001725439 这样一个Long类型的整数,传给前端后会变成201511200001725440

解决方法:

  方法一:在后台将这个Long类型的字段转换成String类型的,风险比较大。

  方法二:使用fastjson的提供的注解,@JSONField(serializeUsing = ToStringSerializer.class)。        

需要导入包:

import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.ToStringSerializer;
@JSONField(serializeUsing = ToStringSerializer.class)
private Long id;

备注:  

  fastjson com.alibaba.fastjson.serializer 包下面提供了多种数据类型转换的注解。

  自己也可以拓展这些注解,通过实现ObjectSerializer 接口来完成。

  ToStringSerializer 的代码:

public class ToStringSerializer implements ObjectSerializer {

    public static final ToStringSerializer instance = new ToStringSerializer();

    @Override
    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
                      int features) throws IOException {
        SerializeWriter out = serializer.out;

        if (object == null) {
            out.writeNull();
            return;
        }

        String strVal = object.toString();
        out.writeString(strVal);
    }

}
@Configuration
public class SessionConfig implements WebMvcConfigurer{
    
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fjc = new FastJsonConfig();
        /**
         * 序列换成json时,将所有的long变成string
         * 因为js中得数字类型不能包含所有的java long值
         */
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(Long.class , ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE , ToStringSerializer.instance);
        fjc.setSerializeConfig(serializeConfig);
        fastJsonConverter.setFastJsonConfig(fjc);
        converters.add(fastJsonConverter);
    }
}

@ResponseBody用fastjson输出fastjson将long转为String输出

js遇到long过长,精度损失,所以改为使用string来传输,但是将long字段改成String的代价太大了,所以直接让fastjson吧long转换成了String

但是@ResponseBody 返回的是Jackson来序列化的,所以要让spring的消息转换器换成fastjson 

maven 添加配置:

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.45</version>
</dependency>

1. 配置@ResponseBody使用fastjson

<mvc:annotation-driven>
    <!-- 重新设置@RequestMapping中对@ResponseBody以String类型消息转换器的字符集 -->
    <mvc:message-converters register-defaults="true">
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg value="UTF-8" />
        </bean>
        <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>text/html;charset=UTF-8</value>
                    <value>application/json</value>
                    <value>application/xml;charset=UTF-8</value>
                </list>
            </property>
            <property name="features">
                <list>
                    <!-- 默认的意思就是不配置这个属性,配置了就不是默认了 -->
                    <!-- 是否输出值为null的字段 ,默认是false-->

                    <value>WriteMapNullValue</value>

                    <value>WriteNullNumberAsZero</value>
                    <value>WriteNullListAsEmpty</value>
                    <value>WriteNullStringAsEmpty</value>
                    <value>WriteNullBooleanAsFalse</value>
                    <value>WriteDateUseDateFormat</value>

                </list>
            </property>
        </bean>
    </mvc:message-converters>

2. Long转String

import java.io.IOException;
import java.lang.reflect.Type;

import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;

public class LongToStringSerializer implements ObjectSerializer {

    public static final LongToStringSerializer instance = new LongToStringSerializer();

    @Override
    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
                    throws IOException {
          SerializeWriter out = serializer.out;

          if (object == null) {
                out.writeNull();
                return;
          }
          String strVal = object.toString();
          out.writeString(strVal);
    }
}

最后编辑于:2020/7/4作者: 编程小战

我不入地狱,谁入地狱?

评论已关闭