Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson detection of duplicate JSON POJO properties and Map keys

Tags:

json

jackson

I'm trying to catch duplicate POJO properties or Map keys are past to my WebService.

So for instance I want to throw an error if field1 appears twice or map key 1 appears twice:

{
  "field1" : 1,
  "field1" : 2,
  "map" : {
    "1" : {
      "fieldA" : "null",
      "fieldB" : "2"
    },
    "1" : {
      "fieldX" : "null",
      "fieldY" : "2"
    }
  }
}
like image 580
DarVar Avatar asked May 21 '14 11:05

DarVar


People also ask

What is the use of Jackson ObjectMapper?

ObjectMapper is the main actor class of Jackson library. ObjectMapper class ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs (Plain Old Java Objects), or to and from a general-purpose JSON Tree Model (JsonNode), as well as related functionality for performing conversions.

Is Jackson ObjectMapper thread-safe?

ObjectMapper is a completely thread-safe service class, it is meant to be used as singleton across the lifetime of the application. It is also very expensive to create.

Should you inject ObjectMapper?

Yes, that is safe and recommended.

What is the use of ObjectMapper readValue?

The simple readValue API of the ObjectMapper is a good entry point. We can use it to parse or deserialize JSON content into a Java object. Also, on the writing side, we can use the writeValue API to serialize any Java object as JSON output.


2 Answers

Can use JsonParser.Feature.STRICT_DUPLICATE_DETECTION

ObjectMapper mapper = new ObjectMapper();
mapper.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION);
MyPOJO result = mapper.readValue(json, MyPOJO.class);

Results in:

com.fasterxml.jackson.core.JsonParseException: Duplicate field 'field1'

How to use Jackson to validate duplicated properties? post about DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY

like image 166
varren Avatar answered Oct 19 '22 21:10

varren


Have a look at this discussion: http://jackson-users.ning.com/forum/topics/detecting-duplicate-field

Here is an example code that comes out from it for a Map class:

public class JacksonDuplicates {

    private static final String JSON = "{\n" +
            "  \"field1\" : 1,\n" +
            "  \"field1\" : 2,\n" +
            "  \"map\" : {\n" +
            "    \"1\" : {\n" +
            "      \"fieldA\" : \"null\",\n" +
            "      \"fieldB\" : \"2\"\n" +
            "    },\n" +
            "    \"1\" : {\n" +
            "      \"fieldX\" : \"null\",\n" +
            "      \"fieldY\" : \"2\"\n" +
            "    }\n" +
            "  }\n" +
            "}";

    private static class SingleKeyHashMap<K, V> extends HashMap<K, V> {
        @Override
        public V put(K key, V value) {
            if (containsKey(key)) {
                throw new IllegalArgumentException("duplicate key " + key);
            }
            return super.put(key, value);
        }
    }

    public static void main(String[] args) throws IOException {
        SimpleModule module = new SimpleModule();
        module.addAbstractTypeMapping(Map.class, SingleKeyHashMap.class);
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(module);

        mapper.readValue(JSON, Map.class);

    }
}

Output:

Exception in thread "main" java.lang.IllegalArgumentException: duplicate key field1
    at jackson.JacksonDuplicates$SingleKeyHashMap.put(JacksonDuplicates.java:38)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringMap(MapDeserializer.java:434)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:312)
    at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:26)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2993)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2098)
    at jackson.JacksonDuplicates.main(JacksonDuplicates.java:50)
like image 42
Alexey Gavrilov Avatar answered Oct 19 '22 20:10

Alexey Gavrilov