#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-код и не анализируйте его, а получите поток событий и проверьте, что здесь написано. Там вы, вероятно, можете просто посмотреть на события и игнорировать все, кроме первого имени каждого имени.