
本文详解如何使用 @JsonProperty 注解在 Jackson 库中精确控制序列化(Java → JSON)和反序列化(JSON → Java)时的字段名称映射,解决跨系统接口中命名不一致(如 created_on ↔ createdOn)导致的数据丢失问题。
本文详解如何使用 `@jsonproperty` 注解在 jackson 库中精确控制序列化(java → json)和反序列化(json → java)时的字段名称映射,解决跨系统接口中命名不一致(如 `created_on` ↔ `createdon`)导致的数据丢失问题。
在微服务或 API 封装场景中,常遇到上下游系统采用不同命名规范的问题:上游(Source A)返回下划线风格字段(如 "created_on"),中间层(Wrapper API B)需正确解析该字段,而下游(Destination C)则期望驼峰风格(如 createdOn)。若未显式配置映射规则,Jackson 默认按 Java 属性名严格匹配 JSON 键名,导致字段无法绑定(如 createdOn 被忽略,仅 id 成功映射)。
关键在于:@JsonProperty 不仅用于反序列化(读取 JSON 时将 "created_on" 映射到 createdOn 字段),也自动参与序列化(将 createdOn 的值以 "created_on" 或指定名称输出)。但本例需求恰恰相反——Wrapper API B 需向下游 C 输出 "createdOn" 字段名,而非沿用上游的 "created_on"。
因此,正确的做法是:在 Wrapper API B 的响应 POJO(即返回给 C 的对象)中,使用 @JsonProperty("createdOn") 明确声明该字段在 JSON 中的序列化名称:
public class BResponse {
private Long id;
// 反序列化时接受 "created_on",序列化时输出 "createdOn"
@JsonProperty("created_on")
private String createdOn; // 注意:此处属性名仍为 createdOn(驼峰),但注解指定源字段
// 必须提供 getter/setter,Jackson 依赖它们访问字段
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getCreatedOn() { return createdOn; }
public void setCreatedOn(String createdOn) { this.createdOn = createdOn; }
}
⚠️ 重要注意事项:
- @JsonProperty("xxx") 若标注在字段上,则同时影响序列化与反序列化;若标注在getter 方法上,则仅控制序列化(输出 JSON 时的键名);若标注在setter 方法上,则仅控制反序列化(解析 JSON 时的键名)。推荐统一标注在字段上以保证行为明确。
- 确保类中存在对应的 getter/setter 方法,否则 Jackson 默认无法访问私有字段(除非启用 @JsonAutoDetect 或配置 Mapper.setVisibility())。
- 若 Wrapper API B 使用 Spring Boot,默认已启用 jackson-databind,无需额外依赖;检查是否误配置了 PropertyNamingStrategies.SNAKE_CASE 全局策略,它会覆盖 @JsonProperty 的局部设置——此时应优先移除全局策略,改用注解精准控制。
- 测试验证:构造 BResponse 实例并调用 ObjectMapper.writeValueAsString(),输出应为 {"id":1,"createdOn":"27July"};反之,用相同 ObjectMapper 解析 {"id":1,"created_on":"27July"} 也能正确赋值。
总结:@JsonProperty 是 Jackson 中处理字段名映射最直接、最可靠的方式。面对多系统集成中的命名差异,应避免依赖全局命名策略,转而采用细粒度注解,在关键 DTO 类中显式声明序列化/反序列化行为,确保数据在各层级间准确无损传递。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











