一、response body 序列化Date与Long为String
方法1-配置 ResponseBody 中 Date 序列化
在application.yml中增加如下配置:
spring:
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
注意:该方法只针对于 springboo t默认的 jackson 序列化才有效,并且该方法只能配置日期相关
方法2-自定义序列化ObjectMap
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter httpMessageConverter : converters){
if(httpMessageConverter instanceof MappingJackson2HttpMessageConverter){
((MappingJackson2HttpMessageConverter) httpMessageConverter).setObjectMapper(new JacksonMapper());
}
}
}
}
public class JacksonMapper extends ObjectMapper {
public JacksonMapper() {
super();
this.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
this.configure(JsonGenerator.Feature.IGNORE_UNKNOWN, true);
this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// null 值属性也序列化
this.setSerializationInclusion(JsonInclude.Include.ALWAYS);
// Long 值转string,解决前端因 Long 值太大而损失精度问题
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
simpleModule.addSerializer(long.class, ToStringSerializer.instance);
//设置日期格式
SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd");
setDateFormat(smt);
registerModule(simpleModule);
}
}
注意:该方法只针对于 springboo t默认的 jackson 序列化才有效,并且会覆盖方法一中的配置
方法三-注册MappingJackson2HttpMessageConverter对象
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
return new MappingJackson2HttpMessageConverter(new JacksonMapper());
}
JacksonMapper 类同方法二
注意:该方法只针对于 springboo t默认的 jackson 序列化才有效,并且会覆盖方法一中的配置
说明:方法二与方法三是在org.springframework.http.converter.HttpMessageConverter层面,重构ObjectMap对象的方式
方法四-注册org.springframework.boot.autoconfigure.http.HttpMessageConverters对象
@Bean
public HttpMessageConverters useConverters() {
// 1.需要定义一个convert转换消息的对象;
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
// 2:添加fastJson的配置信息;
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,
SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue);
fastJsonConfig.setDateFormat("yyyy-mm-dd");
SerializeConfig serializeConfig = SerializeConfig.globalInstance;
serializeConfig.put(Long.class , ToStringSerializer.instance);
serializeConfig.put(Long.TYPE , ToStringSerializer.instance);
fastJsonConfig.setSerializeConfig(serializeConfig);
// 3处理中文乱码问题
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
// 4.在convert中添加配置信息.
fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
HttpMessageConverter<?> converter = fastJsonHttpMessageConverter;
return new HttpMessageConverters(converter);
}
注意:该方法是替换 springboot 默认的 jackson 序列化方式,采用 fastjson 方式序列化
说明:方法二三四是在不同的层面解决序列化问题,不同的序列化方式都可以在这两个层面着手解决序列化问题,在这里我就不一一写明,大家举一反三即可。
二、RequestMapping 时,将前端字符串格式的Date参数反序列化解析
该问题解决只需要实现org.springframework.core.convert.converter.Converter接口即可
@Slf4j
@Component
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
if (StringUtils.isBlank(source)) {
return null;
}
if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) {
return parseDate(source.trim(), "yyyy-MM-dd");
}
if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")) {
return parseDate(source.trim(), "yyyy-MM-dd HH:mm:ss");
}
throw new IllegalArgumentException("Invalid value '" + source + "'");
}
public Date parseDate(String dateStr, String format) {
Date date = null;
try {
date = new SimpleDateFormat(format).parse(dateStr);
} catch (ParseException e) {
log.warn("转换{}为日期(pattern={})错误!", dateStr, format);
}
return date;
}
}
注意:Converter接口中泛型前一个是指原类型,后一个是目标类型
说明:同理,其他类型的转化也是时间该接口即可,大家举一反三