Java 17+Spring Boot 3:多格式JSON日期反序列化求助
解决方案
要处理三种不同格式的日期字符串反序列化为LocalDateTime,需要为每个字段指定匹配的格式模式,并配置时区和locale确保正确解析。以下是具体实现步骤:
1. 实体类修改
为每个日期字段添加@JsonFormat注解,指定对应的格式、时区和locale:
@Data @NoArgsConstructor @AllArgsConstructor public class Response { // 匹配格式:"Sep 13, 2023 19:24:00 UTC" @JsonFormat( shape = JsonFormat.Shape.STRING, pattern = "MMM dd, yyyy HH:mm:ss zzz", timezone = "UTC", locale = "en_US" ) private LocalDateTime updated; // 匹配格式:"2023-09-13T19:24:00+00:00"(标准ISO偏移格式) @JsonFormat( shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssXXX" ) private LocalDateTime updatedISO; // 匹配格式:"Sep 13, 2023 at 20:24 BST" @JsonProperty("updateduk") @JsonFormat( shape = JsonFormat.Shape.STRING, pattern = "MMM dd, yyyy 'at' HH:mm zzz", timezone = "Europe/London", locale = "en_US" ) private LocalDateTime updatedUK; }
注解参数说明:
- pattern:严格匹配JSON中的日期字符串格式,其中:
MMM:匹配英文月份缩写(如Sep)zzz:匹配时区缩写(如UTC、BST)XXX:匹配ISO格式的时区偏移(如+00:00)- 单引号包裹的
'at':匹配JSON中的固定字符串
- timezone:指定字段对应的时区,将带时区的日期转换为无时区的
LocalDateTime - locale:设置为英文,保证月份缩写解析正确
2. 确保Jackson JavaTimeModule注册
Spring Boot 3默认会自动注册JavaTimeModule(用于支持Java 8+时间API),如果遇到序列化/反序列化问题,可以手动配置ObjectMapper:
@Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); JavaTimeModule javaTimeModule = new JavaTimeModule(); objectMapper.registerModule(javaTimeModule); // 禁用日期转为时间戳的序列化方式 objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return objectMapper; } }
3. 测试反序列化
使用ObjectMapper验证反序列化逻辑:
public class TestDeserialization { public static void main(String[] args) throws JsonProcessingException { String json = """ { "updated": "Sep 13, 2023 19:24:00 UTC", "updatedISO": "2023-09-13T19:24:00+00:00", "updateduk": "Sep 13, 2023 at 20:24 BST" } """; ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); Response response = mapper.readValue(json, Response.class); System.out.println(response.getUpdated()); // 输出:2023-09-13T19:24 System.out.println(response.getUpdatedISO()); // 输出:2023-09-13T19:24 System.out.println(response.getUpdatedUK()); // 输出:2023-09-13T20:24 } }
关键注意点
LocalDateTime本身不包含时区信息,反序列化时通过timezone参数将带时区的日期转换为对应时区的本地时间- 必须指定
locale = "en_US",否则Jackson无法解析英文月份缩写(如Sep) - 格式模式必须严格匹配JSON字符串,包括空格、固定字符(如
at)
内容的提问来源于stack exchange,提问作者mh377
相关产品推荐
相关产品推荐

