1.实现WebMvcConfigurer 类中的configureMessageConverters和addFormatters方法
package com.pulpy.knowl.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
//@EnableWebMvc表示完全自己控制mvc配置,也就是说所有配置自己重写,所有默认配置都没了
//@EnableWebMvc
@Configuration
public class HttpMessageConverterConfig implements WebMvcConfigurer {
/**
* 解决前端js处理大数字丢失精度问题
* 将Long和BigInteger转换成string
* 将LocalDatetime等时间类转出string
* 反序列化json中string转换成LocalDatetime等时间类
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = NewObjectMapper.newObjectMapper();
converter.setObjectMapper(objectMapper);
converters.add(0, converter);//最高优先级
}
/**
* 反序列化form-data格式的string转换成LocalDateTime等时间类
*/
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new LocalDateTimeConverter.StringToLocalDateTimeConverter());
registry.addConverter(new LocalDateTimeConverter.StringToLocalDateConverter());
registry.addConverter(new LocalDateTimeConverter.StringToLocalTimeConverter());
}
}
2.string转各种时间类 转化器
package com.pulpy.knowl.config;
import com.pulpy.common.core.utils.StringUtils;
import org.springframework.core.convert.converter.Converter;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class LocalDateTimeConverter {
/**
* 因为 Spring 默认不支持将 String 类型的请求参数转换为 LocalDateTime 类型,所以我们需要自定义 converter 「转换器」完整整个转换过程
*/
public static class StringToLocalDateTimeConverter implements Converter<String, LocalDateTime> {
@Override
public LocalDateTime convert(String s) {
if(StringUtils.isBlank(s)){
return null;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateConstant.PATTERN, Locale.CHINESE);
return LocalDateTime.parse(s, formatter);
}
}
public static class StringToLocalDateConverter implements Converter<String, LocalDate> {
@Override
public LocalDate convert(String s) {
if(StringUtils.isBlank(s)){
return null;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateConstant.PATTERN_YYYY_MM_DD, Locale.CHINESE);
return LocalDate.parse(s, formatter);
}
}
public static class StringToLocalTimeConverter implements Converter<String, LocalTime> {
@Override
public LocalTime convert(String s) {
if(StringUtils.isBlank(s)){
return null;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateConstant.PATTERN_HH_MM_SS, Locale.CHINESE);
return LocalTime.parse(s, formatter);
}
}
}
3.创建新ObjectMapper,定义json 序列化 及 反序列化 类型
package com.pulpy.knowl.config;
import com.fasterxml.jackson.core.JsonParser;
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 com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class NewObjectMapper {
public static ObjectMapper newObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
// result.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.registerModules(newJavaTimeModule(), newSimpleModule());
return objectMapper;
}
public static JavaTimeModule newJavaTimeModule(){
JavaTimeModule javaTimeModule = new JavaTimeModule();
//序列化LocalDateTime等时间类
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateConstant.getFormatter(DateConstant.PATTERN)));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateConstant.getFormatter(DateConstant.PATTERN_YYYY_MM_DD)));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateConstant.getFormatter(DateConstant.PATTERN_HH_MM_SS)));
//反序列化 json格式中 字符串 为LocalDateTime等时间类
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateConstant.getFormatter(DateConstant.PATTERN)));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateConstant.getFormatter(DateConstant.PATTERN_YYYY_MM_DD)));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateConstant.getFormatter(DateConstant.PATTERN_HH_MM_SS)));
return javaTimeModule;
}
public static SimpleModule newSimpleModule(){
SimpleModule simpleModule = new SimpleModule();
// 序列化成json时,将所有的long变成string 因为js中得数字类型不能包含所有的java long值
simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
return simpleModule;
}
}
时间类工具
package com.pulpy.knowl.config;
import java.time.format.DateTimeFormatter;
public class DateConstant {
public static DateTimeFormatter getFormatter(String formatter){
return DateTimeFormatter.ofPattern(formatter);
}
public static final String PATTERN = "yyyy-MM-dd HH:mm:ss";
public static final String PATTERN_YYYY_MM_DD = "yyyy-MM-dd";
public static final String PATTERN_HH_MM_SS = "HH:mm:ss";
}
注意:如果需要将某系列接口进行序列化或反序列化,可以如下操作
package com.pulpy.knowl.config;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.lang.reflect.Type;
public class CustomMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
/**
* 判断该转换器是否能将请求内容转换成 Java 对象
*/
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
if (super.canRead(clazz, mediaType)) {
ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (ra != null) { // web请求
String uri = ra.getRequest().getRequestURI();
// if (uri.startsWith("/web/")) {
return true;
// }
}
}
// 不需要反序列化
return false;
}
/**
* 判断该转换器是否能将请求内容转换成 Java 对象
*/
@Override
public boolean canRead(Type type, Class<?> contextClass, MediaType mediaType) {
if (super.canRead(type, contextClass, mediaType)) {
ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (ra != null) { // web请求
String uri = ra.getRequest().getRequestURI();
// if (uri.startsWith("/web/")) {
return true;
// }
}
}
// 不需要反序列化
return false;
}
/**
* 判断该转换器是否可以将 Java 对象转换成返回内容.
* 匹配web api(形如/web/xxxx)中的接口方法的返回参数
*/
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
if (super.canWrite(clazz, mediaType)) {
ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (ra != null) { // web请求
String uri = ra.getRequest().getRequestURI();
// if (uri.startsWith("/web/")) {
return true;
// }
}
}
return false;
}
}
再重新1中的configureMessageConverters方法
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
CustomMappingJackson2HttpMessageConverter converter = new CustomMappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = NewObjectMapper.newObjectMapper();
converter.setObjectMapper(objectMapper);
converters.add(0, converter);
}