后端把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