目录
前言
解决方案
具体实现
一、自定义序列化器
二、两种方式指定作用域
1、注解 @JsonSerialize()
2、实现自定义全局配置 WebMvcConfigurer
三、拓展 WebMvcConfigurer接口
章末
前言
小伙伴们大家好,上次做了自定义对象属性拷贝,解决了重构中尽量不要修改原有逻辑的问题,将String类型的字段转换成Date或者LocalDateTime类型。
【对象属性拷贝】⭐️按照需要转换的类型反射设置拷贝后对象的属性-CSDN博客
但是转换完成后还需要修改Date类型的值为带上时区的,比如
”2024-02-05 14:46:26“ 》》》》"2024-02-05 14:46:26 GMT+08:00"
这种借助序列化器实现,可以在很大程度上减少对原有代码的重构
解决方案
自定义一个针对于LocalDateTime字段或者Date类型的序列化器,有两种实现方式,一是使用注解的方式标注哪些实体类中的时间属性需要序列化,二是全局序列化器,在处理返回结果前统一处理
具体实现
一、自定义序列化器
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
@Slf4j
public class DiyLocalDatetimeSerializer extends JsonSerializer<LocalDateTime> {
public static final String DEFAULT_DATE_TIME_FORMAT_WITH_TIME_ZONE = "yyyy-MM-dd HH:mm:ss OOOO";
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT_WITH_TIME_ZONE);
//创建一个DateTimeFormatter实例,使用了DEFAULT_DATE_TIME_FORMAT_WITH_TIME_ZONE常量指定的模式。DateTimeFormatter负责根据指定的模式将ZonedDateTime对象格式化为字符串。
/**
*
* @param localDateTime
* @param jsonGenerator
* @param serializerProvider
* @throws IOException
*/
@Override
public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
ZoneId zoneId = ZoneId.systemDefault();
//获取系统默认的时区
ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
//转换为具有默认时区的ZonedDateTime对象
String format = formatter.format(zonedDateTime);
//格式化ZonedDateTime对象
jsonGenerator.writeString(format);
//将格式化后的字符串写入JSON
}
}
二、两种方式指定作用域
1、注解 @JsonSerialize()
在指定类的属性上面添加该注解,比如需要将user类的time属性加上时区
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.hb.demo.config.DiyLocalDatetimeSerializer;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class User {
private Integer id;
private String name;
private Integer age;
private String address;
private String phone;
private String sex;
@JsonSerialize(using = DiyLocalDatetimeSerializer.class)
private LocalDateTime time;
}
apipost调用接口测试下,测试接口就是简单的查询数据库表中的数据,先来看下未加注解的返回值
2、实现自定义全局配置 WebMvcConfigurer
注解实现的方式虽然简单,但是架不住每个接口都要改,对应的每个接口的实体类也要改,通过实现WebMvcConfigurer接口,重写了WebMvcConfigurer 接口中的消息转换方法来处理 HTTP 消息的转换。
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.hb.demo.config.interceptor.DiyInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(diyConvert());
}
/**
* 自定义消息转换器
* @Bean 标记该方法返回一个由Spring管理的Bean对象
* @return
*/
@Bean
public MappingJackson2HttpMessageConverter diyConvert(){
MappingJackson2HttpMessageConverter mappingJackson2CborHttpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
//用于JSON 数据的序列化和反序列化
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(LocalDateTime.class,new DiyLocalDatetimeSerializer());
//添加针对 LocalDateTime 类型的自定义序列化器 DiyLocalDatetimeSerializer
objectMapper.registerModule(simpleModule);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
//设置JSON 数据中包含目标对象中不存在的属性时,直接忽略这些属性而不是中断反序列化过程。
mappingJackson2CborHttpMessageConverter.setObjectMapper(objectMapper);
return mappingJackson2CborHttpMessageConverter;
}
}
测试下,先将之前的@JsonSerialize注解去掉,结果如下,通过这种方式可以实现接口传输数据过程中所有指定的类型自动处理
三、拓展 WebMvcConfigurer接口
该接口定义了多个方法,可以自行注册拦截器、资源处理器、视图解析器以及自定义参数解析器等。看下可以重写哪些方法,常用的比如拦截器,资源处理器. . . 使用的时候可以自定义各种全局处理器
章末