第一种方案:(包含两种方式)
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; }