使用json-patch后日期格式变更的原因及修复方案咨询
问题:JSON Patch替换日期后格式变为非ISO标准格式
环境与操作细节
- 依赖配置(POM)
<dependency> <groupId>com.github.java-json-tools</groupId> <artifactId>json-patch</artifactId> <version>1.13</version> </dependency>
- 原始JSON Payload
{ "expirationDate": "2022-05-15T01:59:59" }
- 执行的JSON Patch(replace操作)
[ { "op": "replace", "path": "/expirationDate", "value": "2023-05-15T02:59:59" } ]
- 转换代码
JsonNode patched = patch.apply(objectMapper.convertValue(targetCustomer, JsonNode.class)); return objectMapper.treeToValue(patched, Customer.class);
异常现象
转换后expirationDate的格式变为expirationDate=Mon May 15 01:59:59 EDT 2023,但预期格式为ISO标准的expirationDate: "2023-05-15T01:59:59"。
原因分析
核心问题出在Jackson的类型转换逻辑:
- JSON Patch操作仅替换了JSON中的字符串值,本身不会改变格式;
- 当
objectMapper.treeToValue将JsonNode转换为Customer类时,若Customer中expirationDate字段是Date/LocalDateTime等日期类型,Jackson会自动把ISO格式的字符串解析为日期对象; - 后续输出该对象时,Jackson默认使用
EEE MMM dd HH:mm:ss zzz yyyy格式序列化日期,而非保留原ISO字符串格式。
修复方案
方案1:全局配置Jackson日期格式
自定义ObjectMapper,强制使用ISO 8601格式处理日期,推荐使用Java 8+的日期API模块:
ObjectMapper objectMapper = new ObjectMapper(); // 注册Java 8日期模块,禁用时间戳序列化 objectMapper.registerModule(new JavaTimeModule()); objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); // 禁用时区自动调整,避免格式偏移 objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
如果仍使用旧的Date类,可设置全局日期格式:
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"));
方案2:实体类字段添加注解
直接在Customer类的目标字段上指定序列化/反序列化规则,精准控制单个字段的格式:
public class Customer { // 针对Date类型 @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "UTC") private Date expirationDate; // 针对Java 8 LocalDateTime类型 @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") private LocalDateTime expirationDate; // getter/setter 省略 }
方案3:字段改为String类型
若业务无需将该字段作为日期对象处理,直接把Customer中的expirationDate定义为String类型,Jackson会直接保留原始字符串格式,不进行日期解析。
内容的提问来源于stack exchange,提问作者VKP
相关产品推荐
相关产品推荐

