将可变(原始/对象)JSON属性反序列化为使用Jackson的对象 [英] Deserialize mutable (primitive/object) JSON property to object with Jackson

查看:84
本文介绍了将可变(原始/对象)JSON属性反序列化为使用Jackson的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出具有可变属性(例如 label )的JSON对象,该属性可以是原始值(例如字符串)或对象.假设的用例可能是标签的多重翻译的包装:

Given a JSON object having a mutable property (e.g. label) which can be either primitive value (e.g. string) or an object. A hypothetical use-case could be a wrapper for pluralized translation of a label:

{
   "label": "User name"
}

{
   "label": {
       "one": "A label",
       "other": "The labels"
   }
}

目标是使 Jackson 反序列化始终在Java端返回固定的结构.因此,如果给出了原始值,则该值总是会转换为目标POJO的某个属性(例如 other ),即:

The goal is to bring Jackson deserialization always return a fixed structure on the Java-side. Thus, if a primitive value is given it is always translated to a certain property (e.g. other) of the target POJO, i.e.:

public class Translations {
   @JsonDeserialize(using = PluralizedTranslationDeserializer.class)
   public PluralizedTranslation label;
}

public class PluralizedTranslation {
   public String one;
   public String other;  // used as default fields for primitive value
}

当前,通过使用自定义 JsonDeserializer 会检查该属性是否为原始类型:

Currently the issue is solved by using a custom JsonDeserializer which checks whether the property is primitive or not:

public class PluralizedTranslationDeserializer extends JsonDeserializer {
    @Override
    public PluralizedTranslation deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        ObjectCodec oc = jsonParser.getCodec();
        JsonNode node = oc.readTree(jsonParser);
        PluralizedTranslation translation;

        if (node.isTextual()) {
            translation = new PluralizedTranslation();
            translation.other = node.asText();
        } else {
            translation = oc.treeToValue(node, PluralizedTranslation.class);
        }

        return translation;
    }
}

是否有一种更优雅的方法来处理可变的JSON属性,而无需在节点级别运行解码器?

Is there a more elegant approach for handling mutable JSON properties without having a decoder which operates on node level?

推荐答案

您可以使label设置器更通用,并添加一些处理这两种情况的逻辑.

You could make the label setter more generic and add some logic handling the two cases.

public class Translations {
    // Fields omitted.

    @JsonProperty("label")
    public void setLabel(Object o) {
        if (o instanceof String) {
            // Handle the first case
        } else if (o instanceof Map) {
            // Handle the second case
        } else {
            throw new RuntimeException("Unsupported");
        }
    }
}

替代解决方案,它将工厂方法放在PluralizedTranslation类中,而使Translations类不受影响:

Alternative solution, which places the factory method inside the PluralizedTranslation class, leaving the Translations class unaffected:

public class PluralizedTranslation {
    public String one;
    public String other;  // used as default fields for primitive value

    @JsonCreator
    private PluralizedTranslation(Object obj) {
        if (obj instanceof Map) {
            Map map = (Map) obj;
            one = (String) map.get("one");
            other = (String) map.get("other");
        } else if (obj instanceof String) {
            other = (String) obj;
        } else {
            throw new RuntimeException("Unsupported");
        }
    }
} 

请注意,可以将构造函数标记为private,以防止意外使用.

Note that the constructor can be marked as private to prevent unintended usage.

这篇关于将可变(原始/对象)JSON属性反序列化为使用Jackson的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆