Jackson Unmarshalling JSON cu proprietăți necunoscute

1. Prezentare generală

În acest articol, vom arunca o privire asupra procesului de neuniformizare cu Jackson 2.x - în special la modul de a trata conținutul JSON cu proprietăți necunoscute .

Dacă doriți să adânciți și să aflați alte lucruri interesante pe care le puteți face cu Jackson - mergeți la tutorialul principal Jackson.

2. Anulați un JSON cu câmpuri suplimentare / necunoscute

Intrarea JSON vine în toate formele și dimensiunile - și de cele mai multe ori, trebuie să o mapăm la obiecte Java predefinite cu un număr stabilit de câmpuri. Scopul este de a ignora pur și simplu orice proprietăți JSON care nu pot fi mapate la un câmp Java existent .

De exemplu, să spunem că trebuie să eliminăm JSON la următoarea entitate Java:

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

2.1. UnrecognizedPropertyException pe câmpuri necunoscute

Încercarea de a anula un JSON cu proprietăți necunoscute pentru această entitate Java simplă va duce la o excepție 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); }

Acest lucru va eșua cu următoarea excepție:

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. Gestionarea câmpurilor necunoscute folosind ObjectMapper

Acum putem configura ObjectMapper complet pentru a ignora proprietățile necunoscute în JSON:

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

Ar trebui apoi să putem citi acest tip de JSON într-o entitate Java predefinită:

@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. Tratarea câmpurilor necunoscute la nivel de clasă

De asemenea, putem marca o singură clasă ca acceptând câmpuri necunoscute , în locul întregului Jackson ObjectMapper :

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

Acum, ar trebui să putem testa același comportament ca înainte - câmpurile necunoscute sunt pur și simplu ignorate și numai câmpurile cunoscute sunt mapate:

@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. Anulați un JSON incomplet

În mod similar cu câmpurile necunoscute suplimentare, eliminarea unui JSON incomplet - un JSON care nu conține toate câmpurile din clasa Java - nu este o problemă cu 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. Concluzie

Acest articol acoperea deserializarea unui JSON cu proprietăți suplimentare, necunoscute, folosind Jackson.

Acesta este unul dintre cele mai frecvente lucruri de configurat atunci când lucrăm cu Jackson, deoarece este adesea cazul în care trebuie să mapăm rezultatele JSON ale API-urilor REST externe la o reprezentare Java internă a entităților API.

Implementarea tuturor acestor exemple și fragmente de cod poate fi găsită în proiectul meu GitHub.