简体   繁体   中英

Jackson enum deserialization

I'm trying to deserialize json object using jackson and getting exception

`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"])`

This is the object:

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

Phone.java:

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

    protected Type type;

    // setters and getters
}

i've read about jackson enum deserializtion, but there was plain enum and there was used Map. Obviously, field "mobile" is not represented in model, but it's a enum value, so how can i deserialize it?

Your JacksonPhoneBuilder works the same way as Jackson default deserialization. The problem is that it's able to read phones in following form:

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

However in your json object phones are represented as a subobject which can be seen in Java as a Map<PhoneType, String> . One of possible solutions is to use a Converter from Map to List (I assume there may be many phones in one address).

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);
    }
}

Then in your Address class:

public class Address {

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

}

Note that it won't play with your Builders but if you don't do any other custom deserialization then you don't need them - you can rely on Jackson's default behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM