简体   繁体   中英

ObjectMapper - How to convert a Map to POJO

I am new to java and trying to learn about objectmapper. I am using it to convert a map to a pojo. The keys in the map are string and all the values are string values except one which I want to convert to a Map. Please go through the below example code for more clearer picture.

POJO Class:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import javax.annotation.Nonnull;
import java.util.Map;

public class POJOClass {
    private  String              string1;
    private Map<String, String> map1;

    @JsonCreator
    public POJOClass(@Nonnull @JsonProperty(value="String1", required = true) String string1,
                     @Nonnull @JsonProperty(value = "Map1", required = true) Map<String, String> map1) {
        this.string1 = string1;
        this.map1 = map1;
    }

    @Nonnull
    public String getString1() {
        return string1;
    }

    @Nonnull
    public Map<String, String> getMap1() {
        return map1;
    }
}

Test Code:

@Test
public void testPOJOClass() {
    Map<String, String> map = new HashMap<>();
    map.put("String1", "string");
    map.put("Map1", "{\"key1\" : \"value1\", \"key2\":\"value2\", \"key3\" : null }");

    ObjectMapper mapper = new ObjectMapper();
    POJOClass pojoClass = mapper.convertValue(map, POJOClass.class);
}

Exception:

java.lang.IllegalArgumentException: Can not instantiate value of type [map type; class java.util.LinkedHashMap, [simple type, class java.lang.String] -> [simple type, class java.lang.String]] from String value ('{"key1" : "value1", "key2":"value2", "key3" : null }'); no single-String constructor/factory method
 at [Source: N/A; line: -1, column: -1]

    at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3286)
    at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:3212)

Variant Options Tried:

I know that I can keep map1 field also as a String and later on convert it into map using another instance of object mapper, but I want to avoid it. Is there any way to directly convert the string in the test code to the mentioned Pojo directly.

I even tried changing the type of map1 from Map to Map but even that didn't work.

public class CustomerDeserializer extends JsonDeserializer<Map<String, String>> {

    @Override
    public Map<String, String> deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
        final ObjectMapper mapper = (ObjectMapper) p.getCodec();
    return mapper.readValue(p.getText(), new TypeReference<Map<String, String>>() {
    });
    }
}

You can write a customer deserializer, annotate JsonDeserialize on map1 parameter in your constructor @JsonDeserialize(using = CustomerDeserializer.class) @JsonProperty(value = "Map1", required = true) Map<String, String> map1) {

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