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.