Spring Boot中使用Jackson能否将同一JSON属性反序列化两次?
实现Jackson同一JSON属性反序列化至两个字段的方案
你需要将JSON中的registry_link字段同时映射为原始值和自定义处理后的值,之前重复使用@JsonProperty导致字段冲突、@JsonAlias无法满足需求的问题,可通过以下几种方案解决:
方案1:类级别自定义反序列化器
完全控制反序列化流程,一次性给两个字段赋值:
1.1 定义实体类
public class ServiceEntity { private String organizationKey; // 处理后的值 private String registryLink; // 原始值 // 省略getter、setter及无参构造方法(Spring环境需无参构造) }
1.2 编写自定义反序列化器
将原generateOrgKey中的处理逻辑整合到类反序列化器中:
public class ServiceEntityDeserializer extends StdDeserializer<ServiceEntity> { public ServiceEntityDeserializer() { super(ServiceEntity.class); } @Override public ServiceEntity deserialize(JsonParser parser, DeserializationContext context) throws IOException { JsonNode node = parser.getCodec().readTree(parser); String rawRegistryLink = node.get("registry_link").asText(); ServiceEntity entity = new ServiceEntity(); // 保留原始值 entity.setRegistryLink(rawRegistryLink); // 执行自定义逻辑生成organizationKey entity.setOrganizationKey(generateOrgKey(rawRegistryLink)); return entity; } // 原generateOrgKey的核心处理逻辑 private String generateOrgKey(String registryLink) { // 示例:截取链接末尾的组织ID,替换为你的实际逻辑 return registryLink.substring(registryLink.lastIndexOf("/") + 1); } }
1.3 绑定反序列化器到实体类
@JsonDeserialize(using = ServiceEntityDeserializer.class) public class ServiceEntity { // ... 字段及方法 }
方案2:通过@JsonCreator构造方法处理
利用构造方法接收原始值,同时初始化两个字段:
public class ServiceEntity { private String organizationKey; private String registryLink; // 无参构造(Spring环境必填) public ServiceEntity() {} // 用@JsonCreator标记构造方法,接收registry_link字段值 @JsonCreator public ServiceEntity(@JsonProperty("registry_link") String registryLink) { this.registryLink = registryLink; // 同步生成处理后的值 this.organizationKey = generateOrgKey(registryLink); } // 省略getter、setter private String generateOrgKey(String registryLink) { // 你的自定义处理逻辑 return registryLink.replace("https://registry.example.com/org/", ""); } }
方案3:使用@JsonSetter方法统一处理
通过单个setter方法同时赋值两个字段:
public class ServiceEntity { private String organizationKey; private String registryLink; // 省略getter及其他setter public String getOrganizationKey() { return organizationKey; } public String getRegistryLink() { return registryLink; } // 用@JsonSetter指定处理registry_link字段 @JsonSetter("registry_link") public void setRegistryLink(String registryLink) { this.registryLink = registryLink; // 同步生成处理后的值 this.organizationKey = generateOrgKey(registryLink); } private String generateOrgKey(String registryLink) { // 你的自定义处理逻辑 return registryLink.toUpperCase(); } }
为什么之前的方法无效?
- 重复使用
@JsonProperty会导致Jackson字段映射冲突,最终只会将值绑定到最后一个标记的字段; @JsonAlias的作用是给单个字段指定多个JSON属性别名(比如多个不同字段名映射到同一个Java字段),无法实现单个JSON属性映射到多个Java字段。
内容的提问来源于stack exchange,提问作者Echatl
相关产品推荐
相关产品推荐

