【问题标题】:Jackson enum deserialization杰克逊枚举反序列化
【发布时间】:2014-04-03 06:27:20
【问题描述】:

我正在尝试使用 jackson 反序列化 json 对象并遇到异常

`com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "mobile" (class mypack.JacksonPhoneBuilder), not
marked as ignorable (2 known properties: , "phoneType", "value"])  at
[Source: %filelocation%; line: 8, column: 24] (through reference
chain:
mypack.JacksonAddressListBuilder["addresses"]->mypack.JacksonAddressBuilder["phones"]->mypack.JacksonPhoneBuilder["mobile"])`

这是对象:

{
    "addresses": [
    {
        ...
        "phones": {
            "mobile": "+01234567890"
        }
    },
    ...
    ]
}

电话.java:

@JsonDeserialize(builder = JacksonBuilder.class)
public class Phone {    
    protected String value;

    protected Type type;

    // setters and getters
}

我读过关于 jackson 枚举反序列化的信息,但是有普通的枚举 并且有使用地图。显然,“移动”领域不是 在模型中表示,但它是一个枚举值,所以我该如何反序列化 是吗?

【问题讨论】:

  • 这一定是您的 JacksonPhoneBuilder 中的错误。它是您的自定义解串器吗?您的地址模型类是什么?我试图将“电话”节点读取到 Map 并且它有效。枚举已正确反序列化。
  • @LukaszWiktor 我已经更新了这个问题。看起来是这样,但我没有得到,它应该如何正常工作。
  • 一个地址是否只有一部电话?您的 json 对象“电话”字段表明可能有很多,而您的地址类有一个用于单个电话的字段。

标签: java json enums jackson


【解决方案1】:

您的 JacksonPhoneBuilder 与 Jackson 默认反序列化的工作方式相同。问题是它能够读取以下形式的手机:

{
    "type": "mobile",
    "value": "+01234130000"
}

但是,在您的 json 对象中,电话被表示为一个子对象,在 Java 中可以看作是 Map<PhoneType, String>。一种可能的解决方案是使用从地图到列表的转换器(我假设一个地址中可能有很多电话)。

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.Converter;

public class PhoneConverter implements Converter<Map<PhoneType, String>, List<Phone>>{

    public List<Phone> convert(Map<PhoneType, String> phonesMap) {
        List<Phone> phones = new ArrayList<Phone>();
        for (PhoneType phoneType : phonesMap.keySet()) {
            phones.add(new Phone(phoneType, phonesMap.get(phoneType)));
        }
        return phones;
    }

    public JavaType getInputType(TypeFactory typeFactory) {
        return typeFactory.constructMapLikeType(Map.class, PhoneType.class, String.class);
    }

    public JavaType getOutputType(TypeFactory typeFactory) {
        return typeFactory.constructCollectionLikeType(List.class, Phone.class);
    }
}

然后在您的地址类中:

public class Address {

    @JsonDeserialize(converter = PhoneConverter.class)
    protected List<Phone> phones;

}

请注意,它不会与您的 Builders 一起使用,但如果您不执行任何其他自定义反序列化,则不需要它们 - 您可以依赖 Jackson 的默认行为。

【讨论】:

    猜你喜欢
    • 2012-09-10
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    相关资源
    最近更新 更多