springboot解决Long类型值传递给页⾯时精度丢失的问题!最近项⽬中遇到个问题,主键id⽤的Long类型,Long类型超过16位时传递给前端丢失精度。
⽹上搜了下,解决办法有很多,⼤体分为两种,写个全局转换器和在bean主键id上添加注解,其实解决的本质是将Long类型在序列化json 时转为String字符串类型,这样就不存在丢失精度了。
1.全局转换器
springboot2以下的版本写个配置类实现WebMvcConfigurerAdapter重写configureMessageConverters⽅法。
springboot2及其以上的版本写个配置类实现WebMvcConfigurer重写configureMessageConverters⽅法(2以上版本WebMvcConfigurerAdapter已经废弃了,不推荐使⽤)。
代码如下:
package com.thecityos.city.fig;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import t.annotation.Configuration;
import org.springframework.http.MediaType;
import org.verter.HttpMessageConverter;
import org.springframework.fig.annotation.WebMvcConfigurer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.alibaba.fig.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
/**
* @title: WebMvcConfig
* @description: ⾃定义转换
* @author:
* @date 2019-08-03 16:23
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 解决主键Long类型返回给页⾯时,页⾯精度丢失的问题,时间格式化返回
* @param converters
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
//格式化json数据格式
FastJsonConfig fastJsonConfig = new FastJsonConfig();
//序列化时避免精度丢失,转换为字符串
SerializeConfig serializeConfig = SerializeConfig.globalInstance;
serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
serializeConfig.put(Long.class, ToStringSerializer.instance);
serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
fastJsonConfig.setSerializeConfig(serializeConfig);
fastJsonConfig.setDateFormat("yyyy-HH-dd HH:mm:ss");
springboot是啥fastConverter.setFastJsonConfig(fastJsonConfig);
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fastMediaTypes.add(MediaType.APPLICATION_JSON);
fastConverter.setSupportedMediaTypes(fastMediaTypes);
converters.add(0,fastConverter);
}
}
当然你要是hold住全场可以⾃⼰继承WebMvcConfigurationSupport重写configureMessageConverters,特别注意的是,继承该类后springboot的默认⾃动配置会失效,需要你⾃⼰根据需要配置⼀些东西。
PS:⼀些常见的问题,写了后没⽣效,⼤概率是虽然添加了转换器进去,但是没在⾸位或者被后续⼀
些配置挤在了后⾯,因为springmvc 处理时,converters⾥包含很多转换器,但是它匹配到第⼀个转换器后就直接使⽤了,后续转换器⽆效。
我就遇到了项⽬⾥因为引⽤了
<dependency>
<groupId>com.github.rkonovalov</groupId>
<artifactId>json-ignore</artifactId>
<version>1.0.14</version>
</dependency>
这个是解决controller层想屏蔽或者只返回某些字段的⼀个注解依赖。
但它有个类FilterRegister实现了WebMvcConfigurer并且重写了extendMessageConverters 如下:
package com.jfilterponents;
import com.jfilter.EnableJsonFilter;
import org.springframework.beans.factory.annotation.Autowired;
import t.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.verter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.hod.support.HandlerMethodArgumentResolver;
import org.hod.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.fig.annotation.*;
import java.util.List;
/
**
* This class used for register FilterConverter in Spring converter list
*
* <p>Class depends from {@link EnableJsonFilter} annotation
*/
@Configuration
public class FilterRegister implements WebMvcConfigurer {
private FilterConfiguration filterConfiguration;
@Autowired
public FilterRegister(FilterConfiguration filterConfiguration) {
this.filterConfiguration = filterConfiguration;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// Do nothing
}
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
// Do nothing
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
/
/ Do nothing
}
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
// Do nothing
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
// Do nothing
}
@Override
public void addFormatters(FormatterRegistry registry) {
// Do nothing
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// Do nothing
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Do nothing
}
@Override
public void addCorsMappings(CorsRegistry registry) {
// Do nothing
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// Do nothing
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// Do nothing
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
// Do nothing
}
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) { // Do nothing
}
/**
* Add converter if filtration is enabled
*
* @param converters list of {@link HttpMessageConverter}
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
if (filterConfiguration.isEnabled())
converters.add(0, new FilterConverter(filterConfiguration));
}
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) { // Do nothing
}
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) { // Do nothing
}
@Override
public Validator getValidator() {
return null;
}
@Override
public MessageCodesResolver getMessageCodesResolver() {
return null;
}
}
这就导致了,我⾃定义的那个配置类解决Long类型丢失的转换器被挤在了后⾯,所以没有⽣效,真是醉了,后⾯研究了⼀天还是没有啥好的解决办法,除⾮不⽤上⾯那个依赖吧,后续空了再研究。
⽬前的解决办法时,在实体bean的Long类型字段上加
/**
* 主键
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 创建时间
*/
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date createTime;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论