我试图使用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"
}
},
...
]
}
Phone.java:
@JsonDeserialize(builder = JacksonBuilder.class)
public class Phone {
protected String value;
protected Type type;
// setters and getters
}
我已经读过关于杰克逊enum deserializtion的内容,但是有一个简单的枚举 并使用了地图。显然,现场"移动"不是 在模型中表示,但它是一个枚举值,所以我如何反序列化 它?
答案 0 :(得分: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;
}
请注意,它不会与您的构建器一起使用,但如果您不进行任何其他自定义反序列化,那么您不需要它们 - 您可以依赖于Jackson的默认行为。