JsonParser получает 1-й из дубликатов ключей

#java #json #duplicates

Вопрос:

Я создал пользовательский JsonDeserializer, и он отлично работает — за исключением одной вещи.

Всякий раз, когда я пытаюсь создать json с дубликатами ключей, он получает последний экземпляр. Наше требование-получить первый экземпляр, никаких ошибок не требуется.

Я использую JsonParser (класс расширен до JsonDeserializer и переопределяет десериализацию), чтобы получить treenode и вручную выполнить бизнес-логику оттуда.

 {
  "key1":"val1", -> I only need this, discard the rest of same key
  "key1":"val2", -> It's showing this
  "key2":"val3"
}
 

Есть идеи, что мне нужно сделать, чтобы получить первый, а не последний?

 @JsonComponent
public class CustomJsonDeserializer extends JsonDeserializer<TestDTO> {

@Override
public TestDTO deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
        throws IOException, JsonProcessingException {

    Boolean isField1Missing = false;
    Boolean isField2Missing = false;
    Boolean isField3Missing = false;
    Boolean isField4Missing = false;
    Boolean isField5Missing = false;
    String field1 = null;
    String field2 = null;
    String field3 = null;
    Integer field5 = null;

    JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser);

    if (jsonNode.path("field1").isMissingNode()) {
        System.out.println("Missing field1");
        isField1Missing = true;
    } else {
        field1 = determineStringValue(jsonNode, "field1");
    }
    
    if (jsonNode.path("field2").isMissingNode()) {
        System.out.println("Missing field2");
        isField2Missing = true;
    } else {
        field2 = determineStringValue(jsonNode, "field2");
    }
    
    if (jsonNode.path("field3").isMissingNode()) {
        System.out.println("Missing field3");
        isField2Missing = true;
    } else {
        field3 = determineStringValue(jsonNode, "field3");
    }
    
    if (jsonNode.path("field5").isMissingNode()) {
        System.out.println("Missing field5");
        isField5Missing = true;
    } else {
        field5 = determineIntegerValue(jsonNode, "field5");
    }
    
    return new TestDTO(field1, field2, field3, field5, null, isField1Missing, isField2Missing, isField3Missing, isField4Missing, isField5Missing );
}

private String determineStringValue(JsonNode jsonNode, String field) {
    
    String returnStr = null;
    
    if (jsonNode.path(field).isNull()) {
        System.out.println("null field "   field);
        return null;
    }
    
    if (!Objects.isNull(jsonNode.path(field).asText())) {
        returnStr =  jsonNode.path(field).asText();
        System.out.println("value "   field   " "   returnStr);
    }
    
    return returnStr;
}

private Integer determineIntegerValue(JsonNode jsonNode, String field) throws JsonMappingException {
    
    String returnStr = null;
    Integer returnInt = null;
    
    if (jsonNode.path(field).isNull()) {
        System.out.println("null field "   field);
        return null;
    }
    
    if (!Objects.isNull(jsonNode.path(field).asText())) {
        returnStr =  jsonNode.path(field).asText();
        System.out.println("value "   field   " "   returnStr);
    }
    
    try {
        returnInt = Integer.parseInt(returnStr);
    } catch (Exception e) {
        System.out.println(e.getMessage());
//          returnInt = -999;
        throw new JsonMappingException("Not readable Cannot deserialize value of type `java.lang.Integer` from String ""   returnStr   "": not a valid Integer value");
    }
    
    System.out.println(returnInt);
    return returnInt;
}
}
 

Комментарии:

1. Спецификация JSON не гарантирует, что объекты с дублирующимися ключами будут обрабатываться каким-либо определенным образом: «Когда имена внутри объекта не уникальны, поведение программного обеспечения, получающего такой объект, непредсказуемо. «Другими словами: зависимость от какого-либо конкретного поведения для объектов такого рода не соответствует JSON, и ее следует избегать, если целью является совместимость!

2. Я понимаю, но мне нужно обращаться с ними очень специфическим образом. 🙂

3. К сожалению, конфигурация анализатора Json является «специфичной для реализации», поэтому я не знаю, какую реализацию вы в конечном итоге используете и можно ли ее настроить для обработки определенным образом. Если такая конфигурация существует, то Json.createParserFactory(Map<String,?>) это то, как вы ее указываете.

4. На самом деле, подумайте об этом: если бы вы использовали сам JsonParser API, то он мог бы сообщать обо всех трех ключах. Другими словами: не создавайте JSON-код и не анализируйте его, а получите поток событий и проверьте, что здесь написано. Там вы, вероятно, можете просто посмотреть на события и игнорировать все, кроме первого имени каждого имени.

5.^ вот руководство по использованию потокового анализатора