后端把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);
}
}
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


![图片[1]-fastjson将Long类型转换成String类型,解决前后端交互,Java序列化JSON丢失精度问题的方法-JoyCode 斑马快跑](https://qiniu.joycode.com.cn/2022/08/20220812211648763247-1024x640.jpg)
















![[PDF文件格式参考]PDF Reference 1.7-JoyCode 斑马快跑](https://qiniu.joycode.com.cn/2020/10/20201011222013698208.jpeg)

















