springboot2.x项目解决解决long转json前端丢失精度问题(三种方案)

7 篇文章 0 订阅
该博客讲述了在SpringBoot中自定义Jackson配置遇到的问题及解决方案。作者发现多个MappingJackson2HttpMessageConverter导致自定义配置未生效。提出了两种解决办法:一是移除已有转换器后再添加自定义配置;二是使用@Order(0)注解确保自定义配置优先级。
摘要由CSDN通过智能技术生成

第一种方案:(包含两种方式)
 

package com.example.demo.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.text.SimpleDateFormat;
import java.util.List;
import java.util.TimeZone;

@Configuration
//@Order(0)
public class WebDataConvertConfig implements WebMvcConfigurer {

  @Override
  public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    for (int i = converters.size()-1; i >= 0; i--) {
      HttpMessageConverter<?> messageConverter = converters.get(i);
      if (messageConverter instanceof MappingJackson2HttpMessageConverter) {
        converters.remove(i);
      }
    }

    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);
    // 设置为空的字段不返回
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    // 反序列化时候,遇到多余的字段不失败,忽略
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // 指定json转换时间类型的时区
    objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
    // 指定返回的时间格式
    objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    jackson2HttpMessageConverter.setObjectMapper(objectMapper);
    converters.add(jackson2HttpMessageConverter);
  }
}

我想特别说一下,当我按照网上说的这么配置的时候,总是不能生效。后来发现converters里面有好几个MappingJackson2HttpMessageConverter 对象,这里配置的仅仅添加到了converters列表的最后。所以当消息在转json的时候首先遍历到了默认的MappingJackson2HttpMessageConverter对象了,匹配到之后就不再匹配后面的了,所以就不会用自定义配置的了。
那我们的解决方式方案就有两种了。第一种方式,可以在添加新的json配置之前,先遍历converters,把MappingJackson2HttpMessageConverter对象都删除掉。这样添加新的后,就会生效了。因此,加了这么一段代码:
for (int i = converters.size()-1; i >= 0; i--) { HttpMessageConverter<?> messageConverter = converters.get(i); if (messageConverter instanceof MappingJackson2HttpMessageConverter) { converters.remove(i); } }

注意要倒序遍历删除,否则会存在漏网之鱼。
另一个方式就是在类上添加@Order(0)注解,这样springboot启动的时候会首先加载这个类,这样咱们在这里配置的消息转换器就排序converters列表的第一个了,自然就生效了。


第二种方案:

找个可以被扫描到的类,写一个生成Bean的方法如下:

@Bean("jackson2ObjectMapperBuilderCustomizer")
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
    Jackson2ObjectMapperBuilderCustomizer customizer = jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance)
            .serializerByType(Long.TYPE, ToStringSerializer.instance).serializationInclusion(JsonInclude.Include.NON_NULL);
    return customizer;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值