SpringMVC和Jackson解决Long 精度丢失(多方案)

概述

问题描述
Java输出至前端的整数长度超过16位时,前端js在解析整数时,超过16位的整数时,后面的数字会损失精度。

问题原因
JS内置的number类型是基于32位整数,Number类型的最大安全整数为9007199254740991,当Java Long型的值大小超过JS Number的最大安全整数时,超出此范围的整数值可能会被破坏,丢失精度。

解决办法
在后台将整数转换成字符串,围绕这个目标,共探索出5种解决方案,能满足大部分的个性化需求。

解决方案

  1. 过滤器统一拦截
  2. 自定义Serializer序列化类
  3. POJO属性增加注解
  4. 修改Serializers源码
  5. 代码转化

项目环境:

Spring 3.X and Jackson 2.X

1)过滤器统一拦截

配置Spring消息转换器的ObjectMapper类,引用创建的自定义类型转换器类。

  • 创建CustomObjectMapperForJackson类
package com.xiaodajia.framework.util.web.databind;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

public class CustomObjectMapperForJackson extends ObjectMapper {
   
   

	public CustomObjectMapperForJackson() {
   
   
		super();
		// 设置日期转换yyyy-MM-dd HH:mm:ss
		setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		SimpleModule simpleModule = new SimpleModule();
		simpleModule.addSerializer(BigDecimal.class,
				ToStringSerializer.instance);
		simpleModule.addSerializer(BigInteger.class,
				ToStringSerializer.instance);
		simpleModule.addSerializer(Long.class,
				ToStringSerializer.instance);
		simpleModule.addSerializer(Long.TYPE,
				ToStringSerializer.instance);
		registerModule(simpleModule);
	}
}
  • spring-mvc.xml配置objectMapper
<mvc:annotation-driven validator="validator" conversion-service="conversion-service">
    	<mvc:message-converters register-defaults="true">
			<!-- 将StringHttpMessageConverter的默认编码设为UTF-8 -->
			<bean class="org.springframework.http.converter.StringHttpMessageConverter">
		    	<constructor-arg value="UTF-8" />
			</bean>
			<!-- 将Jackson2HttpMessageConverter的默认格式化输出设为true -->
			<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="prettyPrint" value="true"/>
                <property name="objectMapper">
                    <bean class="com.xiaodajia.framework.util.web.databind.CustomObjectMapperForJackson"/>
                </property>
            </bean>			
  		</mvc:message-converters>
	</mvc:annotation-driven>

关键代码
当项目中使用Mybatis持久层框架,如果结果类型设置为resultType="map",将集合数据输出至前端时,Jackson会默认将数组、对象中的数值以BigDecimal类型序列化,如果我们只配置了Long的序列化类,对map中数据是不会生效,还需要在自定义ObjectMapper中配置BigDecimal、BigInteger类的序列化

simpleModule.addSerializer(BigDecimal.class,ToStringSerializerForJackson.instance);
simpleModule
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值