Jackson Unmarshalling JSON с неизвестни свойства

1. Общ преглед

В тази статия ще разгледаме процеса на демаркиране с Jackson 2.x - по-специално как да се справим със JSON съдържание с неизвестни свойства .

Ако искате да се задълбочите и да научите други страхотни неща, които можете да правите с Джаксън - преминете към основния урок за Джаксън.

2. Демаркирайте JSON с допълнителни / неизвестни полета

Входът JSON се предлага във всякакви форми и размери - и през повечето време трябва да го картографираме в предварително дефинирани Java обекти с зададен брой полета. Целта е просто да се игнорират всички JSON свойства, които не могат да бъдат отнесени към съществуващо поле на Java .

Например, да кажем, че трябва да демаршалираме JSON към следния обект на Java:

public class MyDto { private String stringValue; private int intValue; private boolean booleanValue; // standard constructor, getters and setters }

2.1. UnrecognizedPropertyException на неизвестни полета

Опитът да демаршалирате JSON с неизвестни свойства на този прост Java Entity ще доведе до com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException :

@Test(expected = UnrecognizedPropertyException.class) public void givenJsonHasUnknownValues_whenDeserializing_thenException() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a"," + ""intValue":1," + ""booleanValue":true," + ""stringValue2":"something"}"; ObjectMapper mapper = new ObjectMapper(); MyDto readValue = mapper.readValue(jsonAsString, MyDto.class); assertNotNull(readValue); }

Това ще се провали със следното изключение:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "stringValue2" (class org.baeldung.jackson.ignore.MyDto), not marked as ignorable (3 known properties: "stringValue", "booleanValue", "intValue"])

2.2. Справяне с неизвестни полета с помощта на ObjectMapper

Вече можем да конфигурираме пълния ObjectMapper да игнорира неизвестни свойства в JSON:

new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

След това трябва да можем да прочетем този вид JSON в предварително дефиниран Java обект:

@Test public void givenJsonHasUnknownValuesButJacksonIsIgnoringUnknowns_whenDeserializing_thenCorrect() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a"," + ""intValue":1," + ""booleanValue":true," + ""stringValue2":"something"}"; ObjectMapper mapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); MyDto readValue = mapper.readValue(jsonAsString, MyDto.class); assertNotNull(readValue); assertThat(readValue.getStringValue(), equalTo("a")); assertThat(readValue.isBooleanValue(), equalTo(true)); assertThat(readValue.getIntValue(), equalTo(1)); }

2.3. Справяне с неизвестни полета на ниво клас

Можем също така да маркираме един клас като приемащ неизвестни полета , вместо целия Jackson ObjectMapper :

@JsonIgnoreProperties(ignoreUnknown = true) public class MyDtoIgnoreUnknown { ... }

Сега трябва да можем да тестваме същото поведение като преди - неизвестни полета просто се игнорират и се картографират само известни полета:

@Test public void givenJsonHasUnknownValuesButIgnoredOnClass_whenDeserializing_thenCorrect() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a"," + ""intValue":1," + ""booleanValue":true," + ""stringValue2":"something"}"; ObjectMapper mapper = new ObjectMapper(); MyDtoIgnoreUnknown readValue = mapper .readValue(jsonAsString, MyDtoIgnoreUnknown.class); assertNotNull(readValue); assertThat(readValue.getStringValue(), equalTo("a")); assertThat(readValue.isBooleanValue(), equalTo(true)); assertThat(readValue.getIntValue(), equalTo(1)); }

3. Демаркирайте непълния JSON

Подобно на допълнителни неизвестни полета, демаркирането на непълния JSON - JSON, който не съдържа всички полета в класа Java - не е проблем с Jackson:

@Test public void givenNotAllFieldsHaveValuesInJson_whenDeserializingAJsonToAClass_thenCorrect() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a","booleanValue":true}"; ObjectMapper mapper = new ObjectMapper(); MyDto readValue = mapper.readValue(jsonAsString, MyDto.class); assertNotNull(readValue); assertThat(readValue.getStringValue(), equalTo("a")); assertThat(readValue.isBooleanValue(), equalTo(true)); }

4. Заключение

Тази статия обхваща десериализиране на JSON с допълнителни, неизвестни свойства, използвайки Jackson.

Това е едно от най-често срещаните неща за конфигуриране при работа с Jackson, тъй като често се налага да съпоставим резултатите от JSON от външни REST API към вътрешно Java представяне на обектите на API.

Изпълнението на всички тези примери и кодови фрагменти може да се намери в моя проект GitHub.