暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SpringBoot中全局LocalDateTime处理

原创 我为啥没洁癖 2023-12-12
2388

场景

正常接口返回时,会有一些字段是Date或者是LocalDateTime等值,默认是Jackson序列化处理,Date和LocalDateTime会被序列化成带T的时间格式。

其中created是Date类型,updated是LocalDateTime类型

image.png

处理Date

Date、Calender视为一类

响应参数

单个配置Date类型反序列化成指定格式的字符串可以使用@JsonFormat注解指定

@JsonFormat优先级比全局配置优先级高。如全局配置date-format: yyyy-MM-dd HH:mm:ss,注解配置pattern = "yyyy-MM-dd",实际按照注解的格式返回。

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "GMT+8") private Date created;
复制

全局配置

配上jackson的spring配置文件,根据date-format格式会自动格式化Date数据类型。

配置上全局参数相当于Date、Calendar等类型的序列化默认值格式使用我们配置的格式。但是这个对LocalDateTime无效。

spring: jackson: # 设置 java.util.Date, Calendar 序列化、反序列化的格式 date-format: yyyy-MM-dd HH:mm:ss # 当地时区 locale: zh # 设置全局时区 time-zone: GMT+8 # 设置空如何序列化 defaultPropertyInclusion: always serialization: # 禁止将 java.util.Date, Calendar 序列化为数字(时间戳) WRITE_DATES_AS_TIMESTAMPS: false # 格式化输出 indent_output: false # 序列化时,对象为 null,是否抛异常 fail_on_empty_beans: false deserialization: #允许对象忽略json中不存在的属性 fail_on_unknown_properties: false
复制

接收参数

Param参数

在需要接收的时间类型的param参数的位置加上@DateTimeFormat注解并设置对应的解析格式。

接收Param参数不管是Date还是LocalDateTime都需要在参数上加上@DateTimeFormat注解来自定义解析格式。必须加,全局配置无法覆盖

如果是用对象来接收param参数也是要在对象的属性上使用@DateTimeFormat的。

@RequestMapping("/ok") public Object test(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date) { ... }
复制

对象属性

@Data public class MyDate { @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date date; @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Calendar calendar; }
复制

Body参数

正常如果使用@JsonFormat注解的参数或者全局配置,可以自动转换Body参数,不需要额外的操作。

@RequestMapping("/ok") public Object test(@RequestBody MyDate date) { } // 实体类上使用JsonFormat注解或者使用全局配置 @Data public class MyDate { @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date date; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Calendar calendar; }
复制

处理LocalDateTime

LocalDateTime、LocalDate、LocalTime可以视为一类。

响应参数

LocalDateTime的单个响应参数的配置逻辑和Date逻辑一致。

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime updated;
复制

全局配置

自定义Jackson2ObjectMapperBuilderCustomizer实例注入到Spring中,添加LocalDateTime的时间处理模块。

添加了全局化配置后,LocalDateTime等类型就相当于自定义了默认格式化格式。

@Slf4j @Configuration public class JacksonConfig { @Bean public Jackson2ObjectMapperBuilderCustomizer customizer() { return builder -> { // 全局配置序列化返回 JSON 处理 JavaTimeModule javaTimeModule = new JavaTimeModule(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); // LocalDateTime默认格式化: yyyy-MM-ddTHH:mm:ss.SSS javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter)); javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter)); // LocalDate默认格式化: yyyy-MM-dd // LocalDate默认比较符合习惯可以不改 javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter)); javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter)); // LocalTime默认格式化: HH:mm:ss.SSS javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(timeFormatter)); javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(timeFormatter)); builder.modules(javaTimeModule); builder.timeZone(TimeZone.getDefault()); }; } }
复制

接收参数

接收参数和Date类型的逻辑完全一样,不论Param参数还是Body参数。

@RequestMapping("/ok") public Object test(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime date) { ... }
复制

Spring转换器全局配置

对于Date和LocalDateTime的统一处理还可以在WebMvcConfigurer上添加MappingJackson2HttpMessageConverter转换器来解决,将自定义的一些转换器统一进行添加来支持接口响应的转换。

使用这个配置后,相当于Date的全局配置+LocalDateTime的全局配置。更推荐上面的方式

@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); // 全局配置序列化返回 JSON 处理 JavaTimeModule javaTimeModule = new JavaTimeModule(); String pattern = "yyyy-MM-dd HH:mm:ss"; DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern); DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter)); javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter)); javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(timeFormatter)); javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter)); javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter)); javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(timeFormatter)); // 禁止时间字段序列化成时间戳 ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules(javaTimeModule) .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).build(); // 序列化对象null值不抛异常 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // date时间格式化 objectMapper.setDateFormat(new SimpleDateFormat(pattern)); converter.setObjectMapper(objectMapper); converters.add(0, converter); } }
复制

最后修改时间:2023-12-12 15:48:20
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论