js 丢失 Long 精度 解决方案
方法:传给前端时转成String
- 单个
/** * ID */ @JsonSerialize(using = ToStringSerializer.class) private Long id;
- 全局(推荐使用) SpringBoot2
参考:
- SpringBoot全局配置long转String丢失精度的问题解决_java_脚本之家 (jb51.net)
-
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
-
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_31424825/article/details/117809472
/** * WebMvc配置 * * @author : JZDELD * @date : 2021/11/19 14:00 */ @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); /** * 序列换成json时,将所有的long变成string * 因为js中得数字类型不能包含所有的java long值 */ SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); objectMapper.registerModule(simpleModule); /** * 2021/11/27
* 遇到一个问题,手动重写json转换后,前端请求参数中的多余字段,导致请求报错, * 重写前框架自带的方法是不报错的,那只有手动解决了 */ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); jackson2HttpMessageConverter.setObjectMapper(objectMapper); /** * 现在好多项目都用到了long型ID,如果不做处理,返回到前端的精度会丢失,为了解决这个方法, * 只能重写configureMessageConverters,很多人都遇到重写这个不生效的情况,都有分析原因, * 是因为有一个默认的消息转换器排在我们自定义的前面导致不生效,有的说加注解@EnableWebMvc, * 有的说定义一个Bean等等,知道原因后解决其实没那么复杂,我们只需要将自定义的消息转换器放到前边即可, * 下面是代码: */ // index 0 关键 核心就在这里,把它添加到首位还担心他不生效吗 converters.add(0, jackson2HttpMessageConverter); } }
- 更好的全局配置
使用自定义的 JsonSerializer
/** * 如果 long 大于 int 最大值 转成字符串 * * @author JZDELD * @date 2021/11/29 14:06 */ public class LongToLongOrStringSerializer extends JsonSerializer<Long> { /** * Singleton instance to use. */ public final static LongToLongOrStringSerializer instance = new LongToLongOrStringSerializer(); /** * js的number类型有个最大值(安全值)。即2的53次方,为9007199254740992 */ public final static Long JS_LONG_MAX = 0x20000000000000L; /** * 最大的15位数 999,999,999,999,999 */ public final static Long LONG_MAX_DIGITS_15 = 0x38d7ea4c67fffL; @Override public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { if (value == null) { return; } if (value > JS_LONG_MAX) { gen.writeString(value.toString()); } else { gen.writeNumber(value); } } }
WebConfig
/** * WebMvc配置 * * @author : JZDELD * @date : 2018/12/13 16:49 */ @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { for (HttpMessageConverter<?> converter : converters) { // 保留了yml中的jackson配置 if (converter instanceof MappingJackson2HttpMessageConverter) { MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = (MappingJackson2HttpMessageConverter) converter; // MappingJackson2HttpMessageConverter 加上 Long 转 String updateMappingJackson2HttpMessageConverter(jackson2HttpMessageConverter); break; } } } /** * 给 MappingJackson2HttpMessageConverter 加点东西 * * @param jackson2HttpMessageConverter */ private void updateMappingJackson2HttpMessageConverter(MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) { ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper(); /** * 序列换成json时,将所有的long变成string * 因为js中得数字类型不能包含所有的java long值 */ SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(Long.class, LongToLongOrStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, LongToLongOrStringSerializer.instance); objectMapper.registerModule(simpleModule); /** * 遇到一个问题,手动重写json转换后,前端请求参数中的多余字段,导致请求报错, * 重写前框架自带的方法是不报错的,那只有手动解决了 */ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); jackson2HttpMessageConverter.setObjectMapper(objectMapper); } }