springboot的web和openfeign的json的字符串时间互转的序列
化和反序列化
场景描述:前端⼊参的时间格式是字符串,ex:"createTime":"2022-03-08"或者 "createTime":"2022-03-08 16:03:50",后端接受的是Date类型,
jackson会报反序列化异常,这是正常现象,正常思路是要求前后端安装约定参数名和参数类型来交互的,,前端不配合,后端只能
脱裤⼦妥协了,我们兼容你们前端的任性,还有全局返回的时间格式也统⼀是字符串,来下⾯开始
就是请求的时间格式是"createTime":"2022-03-08 16:03:50",响应的response的时间也是"createTime":"2022-03-08
16:03:50",蛋疼啊
开始上代码:
通⽤ObjectMapper配置
import lkit.StringUtils;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
import com.fasterxml.dule.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
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 lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import t.annotation.Bean;
import t.annotation.Configuration;
SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
/**
* 描述: 通⽤ObjectMapper配置 </br>
* 时间: 2020-03-09 9:13 </br>
* 作者:王林冲
*/
@Configuration
public class CommonObjectMapperConfig {
//时间格式数组
private static final List<String> formarts = new ArrayList<>(4);
//年⽉格式
private static final String YYYY_MM = "yyyy-MM";
//年⽉⽇格式
private static final String YYYY_MM_DD = "yyyy-MM-dd";
private static final String YYYY_MM_DD = "yyyy-MM-dd";
//年⽉⽇时分格式
private static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
//年⽉⽇时分秒格式
private static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
//初始加载
static{
formarts.add(YYYY_MM);
formarts.add(YYYY_MM_DD);
formarts.add(YYYY_MM_DD_HH_MM);
formarts.add(YYYY_MM_DD_HH_MM_SS);
}
//ymal配置,不配置就⾛默认值
@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;
@Value("${spring.jackson.time-zone:GMT+8}")
private String timeZone;
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
//设置时区
objectMapper.TimeZone(timeZone));
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//关闭⽇期序列化为时间戳的功能
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
//关闭序列化的时候没有为属性到getter⽅法,报错
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
//序列化的时候序列对象的所有属性
objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
//空值不序列化
//objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//序列化空对象不抛异常
/
/关闭反序列化的时候,没有到属性的setter报错
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
//反序列化未知属性不抛出异常
//⾃定义序列化:key-序列化字段类型,value-序列化所⽤对象,⽀持⾃定义及Jackson⾃带序列化器
SimpleModule module = new SimpleModule();
String[] patternArr = pattern.split(" ");
module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern)));
module.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(patternArr[0])));
module.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(patternArr[1])));
module.addSerializer(Date.class, new DateSerializer(false,new SimpleDateFormat(pattern)));
//⾃定义反序列化:key-序列化字段类型,value-序列化所⽤对象,⽀持⾃定义及Jackson⾃带序列化器
module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(pattern))); module.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(patternArr[0])));
module.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(patternArr[1])));
//设置全局反序列化,string -> date
module.addDeserializer(Date.class, new DateDeserializers.DateDeserializer(){
@SneakyThrows
@Override
public Date deserialize(JsonParser jsonParser, DeserializationContext ctxt){
if (ObjectUtils.Text())){
return null;
}
//获取序列⽂本
String text = Text().trim();
String timeFormat = getTimeFormat(text);
//进⾏时间格式化
SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
return sdf.parse(text);
return sdf.parse(text);
}
});
return objectMapper;
}
/**
* 正则配置获取时间格式 formart
* @param source 时间⽂本字符串
* @return String - 格式化格式
*/
public String getTimeFormat(String source) {
if (StringUtils.isBlank(source)) {
return null;
}
if(source.matches("^\\d{4}-\\d{1,2}$")){
(0);
}else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){
(1);
}else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")){
return (2);
}else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){ (3);
}else {
throw new IllegalArgumentException("Invalid false value '" + source + "'"); }
}
}
string转date的jackson的反序列化全局配置
fig;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import t.annotation.Configuration;
import org.verter.HttpMessageConverter;
import org.verter.json.MappingJackson2HttpMessageConverter;
import org.springframework.fig.annotation.WebMvcConfigurer;
import java.util.List;
/**
* 描述: string转date的jackson的反序列化配置 </br>
* 时间: 2021-12-25 12:23 </br>
* 作者:王林冲
*/
@Configuration
public class JacksonStringToDateConfig implements WebMvcConfigurer {
@Autowired
ObjectMapper objectMapper;
/
**
* 扩展消息转换解析
* @param converters
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter<?> cvt : converters) {
if (cvt instanceof MappingJackson2HttpMessageConverter) {
MappingJackson2HttpMessageConverter converter= (MappingJackson2HttpMessageConverter) cvt; enhanceConvertor(converter);
}
}
}
string转date的方法/**
* 增强转换器
* @param converter
*/
private void enhanceConvertor(MappingJackson2HttpMessageConverter converter) {
converter.setObjectMapper(objectMapper);
}
}
openfeign的反序列化配置
@Configuration
public class feignCoderConfig {
//注⼊通⽤objectMapper
@Autowired
ObjectMapper objectMapper;
@Bean
public Decoder feignDecoder() {
return new ResponseEntityDecoder(new SpringDecoder(messageConverters()));
}
public ObjectFactory<HttpMessageConverters> messageConverters() {
return () -> new HttpMessageConverters(mappingJackson2HttpMessageConverter());
}
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
return new MappingJackson2HttpMessageConverter(objectMapper);
}
}
看到了吗?feignDecoder的HttpMessageConverters的MappingJackson2HttpMessageConverter的
ObjectMapper 和 WebMvcConfigurer的配置的WebMvc的HttpMessageConverters的MappingJackson2HttpMessageConverter 的ObjectMapper都是在CommonObjectMapperConfig配置的统⼀个ObjectMapper,时间的序列化和反序列化⼀样,就变成springboot的web时间序列化反序列化和feign的时间序列化反序列化都是⼀样的,都是字符串来交互;
流程如何:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论