You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jackson反序列化时@JsonUnwrapped注解失效问题求助

解决Jackson反序列化@JsonUnwrapped忽略_l10n字段的问题

问题核心

用@JsonUnwrapped配合自定义序列化器实现了LocalizedField的拆包序列化(将value和value_l10n映射为xxx和xxx_l10n),但反序列化时自定义反序列化器只能拿到xxx节点,无法获取xxx_l10n数据,还需额外添加@JsonIgnoreProperties才能执行逻辑。

解决方案

核心思路是通过ContextualDeserializer获取当前字段的名称,从而拼接出对应的xxx_l10n键名,再从父节点中同时读取两个字段的数据。

1. 实现带上下文感知的反序列化器

让自定义反序列化器实现ContextualDeserializer接口,在初始化时获取当前字段的名称,反序列化时从父节点中读取xxx和xxx_l10n两个节点:

public class LocalizedFieldDeserializer extends JsonDeserializer<LocalizedField> implements ContextualDeserializer {
    private String fieldName;

    @Override
    public LocalizedField deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
        // 获取父节点(包含当前字段的xxx和xxx_l10n)
        JsonNode parentNode = parser.getParsingContext().getParent().getCurrentNode();
        
        // 读取基础值
        String value = parentNode.get(fieldName).asText();
        
        // 读取多语言映射
        JsonNode l10nNode = parentNode.get(fieldName + "_l10n");
        Map<String, String> l10nMap = null;
        if (l10nNode != null && l10nNode.isObject()) {
            l10nMap = ctx.readValue(l10nNode.traverse(), new TypeReference<Map<String, String>>() {});
        }
        
        return new LocalizedField(value, l10nMap);
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctx, BeanProperty property) throws JsonMappingException {
        LocalizedFieldDeserializer deserializer = new LocalizedFieldDeserializer();
        // 保存当前字段的名称(如name、description)
        deserializer.fieldName = property.getName();
        return deserializer;
    }
}

2. 配置LocalizedField类

在LocalizedField上绑定自定义反序列化器,同时保留JPA@Embeddable注解:

@Embeddable
@JsonDeserialize(using = LocalizedFieldDeserializer.class)
public class LocalizedField {
    private String value;
    @JsonProperty("value_l10n")
    private Map<String, String> valueL10n;

    // 构造函数、getter/setter省略
}

3. 实体类中使用@JsonUnwrapped

在包含LocalizedField的实体类字段上保留@JsonUnwrapped,无需再添加@JsonIgnoreProperties:

@Entity
public class Product {
    @Id
    private Long id;
    @JsonUnwrapped
    private LocalizedField name;
    @JsonUnwrapped
    private LocalizedField description;

    // 构造函数、getter/setter省略
}

原理说明

  • ContextualDeserializer能在反序列化时获取当前字段的名称,从而动态找到对应的xxx_l10n节点;
  • 从父节点读取数据,能一次性获取拆包后的两个字段,避免了单个节点的限制;
  • 该方案完全兼容JPA@Embeddable,可在多个实体类中复用LocalizedField。

内容的提问来源于stack exchange,提问作者Kariem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:58:11