你们好,我是金金金。
场景
- 场景如下: 获取数据,里面日期字段返回给到前端的是一个数组类型
解决
前端后端都可以解决,前端处理方式:自定义函数处理时间;后端处理方式:1.
@JsonFormat
2.全局序列化日期格式处理
这里实现后端全局序列化日期格式处理(这种方式也更为友好)
- 定义
JacksonObjectMapper
继承ObjectMapper
(确保日期格式统一,同时提升系统的健壮性和兼容性)
java
public class JacksonObjectMapper extends ObjectMapper {
// 常量集中管理,便于统一修改
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
// 预定义Formatter避免重复创建
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT);
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT);
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT);
/**
* 构造函数,初始化JacksonObjectMapper对象
* 调用父类的构造函数,并配置通用设置和日期处理方式
*/
public JacksonObjectMapper() {
super(); // 调用父类的构造函数
configureCommonSettings(); // 配置通用的序列化和反序列化设置
configureDateHandling(); // 配置日期的处理方式
}
/**
* 配置通用设置方法
* 该方法统一配置了JSON处理时的一些通用设置,以确保整个应用中对JSON的处理保持一致
*/
private void configureCommonSettings() {
// 统一处理未知属性(序列化+反序列化)
// 设置为false表示在反序列化时忽略未知属性,在序列化时允许空对象
this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 可选:设置全局时区(根据项目需求调整)
// 这里设置的是上海时区,可以根据实际情况修改为其他时区
this.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
}
/**
* 配置日期处理方式
* 该方法通过添加自定义的序列化器和反序列化器来配置如何处理日期类型的字段
* 同时,确保日期类型字段不会被默认处理为timestamp格式
*/
private void configureDateHandling() {
// 创建一个模块来定义日期类型的序列化和反序列化行为
SimpleModule dateModule = new SimpleModule();
// 添加自定义的日期反序列化器
addDeserializers(dateModule);
// 添加自定义的日期序列化器
addSerializers(dateModule);
// 将配置好的模块注册到当前对象中
this.registerModule(dateModule);
// 确保其他日期类型(如ZonedDateTime)不使用timestamp格式
this.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
/**
* 向SimpleModule中添加反序列化器
* 该方法用于将自定义的日期时间反序列化器注册到模块中,以便在序列化和反序列化过程中处理特定格式的日期时间数据
*
* @param module SimpleModule的实例,用于添加反序列化器
*/
private void addDeserializers(SimpleModule module) {
// 添加LocalDateTime的反序列化器,使用全局的DATE_TIME_FORMATTER格式化器
module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DATE_TIME_FORMATTER))
// 添加LocalDate的反序列化器,使用全局的DATE_FORMATTER格式化器
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DATE_FORMATTER))
// 添加LocalTime的反序列化器,使用全局的TIME_FORMATTER格式化器
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(TIME_FORMATTER));
}
/**
* 向SimpleModule中添加序列化器
* 该方法用于将自定义的序列化器注册到模块中,以便在序列化和反序列化过程中处理特定类型
*
* @param module SimpleModule实例,用于添加序列化器
*/
private void addSerializers(SimpleModule module) {
// 添加LocalDateTime类型的序列化器,使用DATE_TIME_FORMATTER格式化日期和时间
module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DATE_TIME_FORMATTER))
// 添加LocalDate类型的序列化器,使用DATE_FORMATTER格式化日期
.addSerializer(LocalDate.class, new LocalDateSerializer(DATE_FORMATTER))
// 添加LocalTime类型的序列化器,使用TIME_FORMATTER格式化时间
.addSerializer(LocalTime.class, new LocalTimeSerializer(TIME_FORMATTER));
}
}
WebMvcConfig
扩展消息转换器列表
java
@RequiredArgsConstructor
@Configuration
@Slf4j
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 扩展消息转换器列表
* <p>
* 该方法用于在Spring Boot的Web配置中添加或修改HTTP消息转换器
* 它的存在使得我们可以自定义消息转换的行为,例如如何序列化和反序列化JSON
*
* @param converters 消息转换器的列表,我们可以向其中添加新的转换器或修改现有的转换器
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("扩展消息转换器...");
// 创建一个新的MappingJackson2HttpMessageConverter实例
// 这个转换器用于处理JSON格式的数据
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
// 为转换器设置一个自定义的ObjectMapper
// ObjectMapper是Jackson库中用于处理JSON序列化和反序列化的类
// 这里使用JacksonObjectMapper,它可能配置了一些特定的序列化或反序列化规则
converter.setObjectMapper(new JacksonObjectMapper());
// 将新创建的转换器添加到转换器列表的开头
// 这样做是为了确保我们的转换器优先于其他转换器被使用
converters.add(0, converter);
}
}
测试
总结
1. JacksonObjectMapper
的作用
- 直接控制序列化/反序列化规则 :
所有经过它的Java对象和JSON数据,都会按照你定义的格式(如日期格式)和规则(如忽略未知字段)处理。
2. WebMvcConfig
的作用
- 替换Spring的默认翻译官 :
Spring Boot默认会注册一个ObjectMapper
,但你的配置覆盖了它,确保所有HTTP请求和响应都使用你的定制规则。
- 编写有误还请大佬指正,万分感谢。