10

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"
    }
  }
}
ᄂ ᄀ
  • 5,669
  • 6
  • 43
  • 57
DarVar
  • 16,882
  • 29
  • 97
  • 146

2 Answers2

30

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

Community
  • 1
  • 1
varren
  • 14,551
  • 2
  • 41
  • 72
5

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)
Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48
  • How can this be configured in a JAX-RS applciation? – DarVar May 26 '14 at 21:46
  • There are few ways to accomplish that depending on your use case. For example [this wiki page](http://wiki.fasterxml.com/JacksonFAQJaxRs) describes how to configure the object mapper for a given mime type. – Alexey Gavrilov May 26 '14 at 22:09
  • Think I found a solution http://jackson-users.ning.com/forum/topics/configuring-custom-modules-when-using-jaxrs-provider – DarVar May 26 '14 at 22:13
  • This technically works, but it's a hack. varren's answer is the "right" one. – Cannoliopsida Oct 03 '18 at 14:42