Jackson JSON Views

Jackson Top

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO

1. Panoramica

In questo tutorial, esamineremo come utilizzare Jackson JSON Views per serializzare / deserializzare oggetti, personalizzare le visualizzazioni e, infine, come iniziare a integrarsi con Spring.

2. Serializzare utilizzando viste JSON

Innanzitutto, passiamo attraverso un semplice esempio: serializza un oggetto con @JsonView .

Ecco il nostro punto di vista:

public class Views { public static class Public { } }

E l' entità " Utente ":

public class User { public int id; @JsonView(Views.Public.class) public String name; }

Ora serializziamo un'istanza " Utente " utilizzando la nostra vista:

@Test public void whenUseJsonViewToSerialize_thenCorrect() throws JsonProcessingException { User user = new User(1, "John"); ObjectMapper mapper = new ObjectMapper(); mapper.disable(MapperFeature.DEFAULT_VIEW_INCLUSION); String result = mapper .writerWithView(Views.Public.class) .writeValueAsString(user); assertThat(result, containsString("John")); assertThat(result, not(containsString("1"))); }

Nota come, poiché stiamo serializzando con una vista specifica attiva, stiamo vedendo solo i campi giusti che vengono serializzati .

È anche importante capire che, per impostazione predefinita, tutte le proprietà non contrassegnate in modo esplicito come parte di una vista vengono serializzate. Stiamo disabilitando questo comportamento con la pratica funzione DEFAULT_VIEW_INCLUSION .

3. Utilizzare più visualizzazioni JSON

Successivamente, vediamo come utilizzare più viste JSON, ognuna con campi diversi come nell'esempio seguente:

Qui dobbiamo vedere dove Interno si estende Pubblico , con la vista interna che estende quella pubblica:

public class Views { public static class Public { } public static class Internal extends Public { } }

Ed ecco la nostra entità " Item " dove solo i campi id e name sono inclusi nella visualizzazione Pubblica :

public class Item { @JsonView(Views.Public.class) public int id; @JsonView(Views.Public.class) public String itemName; @JsonView(Views.Internal.class) public String ownerName; }

Se usiamo la visualizzazione Pubblica per serializzare, solo l' ID e il nome verranno serializzati in JSON:

@Test public void whenUsePublicView_thenOnlyPublicSerialized() throws JsonProcessingException { Item item = new Item(2, "book", "John"); ObjectMapper mapper = new ObjectMapper(); String result = mapper .writerWithView(Views.Public.class) .writeValueAsString(item); assertThat(result, containsString("book")); assertThat(result, containsString("2")); assertThat(result, not(containsString("John"))); }

Ma se usiamo la vista interna per eseguire la serializzazione, tutti i campi faranno parte dell'output JSON:

@Test public void whenUseInternalView_thenAllSerialized() throws JsonProcessingException { Item item = new Item(2, "book", "John"); ObjectMapper mapper = new ObjectMapper(); String result = mapper .writerWithView(Views.Internal.class) .writeValueAsString(item); assertThat(result, containsString("book")); assertThat(result, containsString("2")); assertThat(result, containsString("John")); }

4. Deserializza utilizzando viste JSON

Ora, vediamo come utilizzare le viste JSON per deserializzare gli oggetti, in particolare un'istanza utente :

@Test public void whenUseJsonViewToDeserialize_thenCorrect() throws IOException { String json = "{"id":1,"name":"John"}"; ObjectMapper mapper = new ObjectMapper(); User user = mapper .readerWithView(Views.Public.class) .forType(User.class) .readValue(json); assertEquals(1, user.getId()); assertEquals("John", user.getName()); }

Nota come stiamo usando l' API readerWithView () per creare un ObjectReader usando la vista data.

5. Personalizza le viste JSON

Successivamente, vediamo come personalizzare le visualizzazioni JSON. Nel prossimo esempio - vogliamo fare l'utentenome ” UpperCase nel risultato serializzazione.

Useremo BeanPropertyWriter e BeanSerializerModifier per personalizzare la nostra vista JSON. Primo: ecco BeanPropertyWriter UpperCasingWriter per trasformare il nome utente in maiuscolo:

public class UpperCasingWriter extends BeanPropertyWriter { BeanPropertyWriter _writer; public UpperCasingWriter(BeanPropertyWriter w) { super(w); _writer = w; } @Override public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception { String value = ((User) bean).name; value = (value == null) ? "" : value.toUpperCase(); gen.writeStringField("name", value); } }

Ed ecco il BeanSerializerModifier per impostare il nome utente BeanPropertyWriter con il nostro UpperCasingWriter personalizzato :

public class MyBeanSerializerModifier extends BeanSerializerModifier{ @Override public List changeProperties( SerializationConfig config, BeanDescription beanDesc, List beanProperties) { for (int i = 0; i < beanProperties.size(); i++) { BeanPropertyWriter writer = beanProperties.get(i); if (writer.getName() == "name") { beanProperties.set(i, new UpperCasingWriter(writer)); } } return beanProperties; } }

Ora serializziamo un'istanza utente utilizzando il serializzatore modificato:

@Test public void whenUseCustomJsonViewToSerialize_thenCorrect() throws JsonProcessingException { User user = new User(1, "John"); SerializerFactory serializerFactory = BeanSerializerFactory.instance .withSerializerModifier(new MyBeanSerializerModifier()); ObjectMapper mapper = new ObjectMapper(); mapper.setSerializerFactory(serializerFactory); String result = mapper .writerWithView(Views.Public.class) .writeValueAsString(user); assertThat(result, containsString("JOHN")); assertThat(result, containsString("1")); }

6. Utilizzo delle viste JSON con Spring

Infine, diamo una rapida occhiata all'utilizzo delle visualizzazioni JSON con Spring Framework . Possiamo sfruttare l' annotazione @JsonView per personalizzare la nostra risposta JSON a livello di API.

Nell'esempio seguente, abbiamo utilizzato la visualizzazione pubblica per rispondere:

@JsonView(Views.Public.class) @RequestMapping("/items/{id}") public Item getItemPublic(@PathVariable int id) { return ItemManager.getById(id); }

La risposta è:

{"id":2,"itemName":"book"}

E quando abbiamo utilizzato la vista interna come segue:

@JsonView(Views.Internal.class) @RequestMapping("/items/internal/{id}") public Item getItemInternal(@PathVariable int id) { return ItemManager.getById(id); }

Questa è stata la risposta:

{"id":2,"itemName":"book","ownerName":"John"}

Se vuoi approfondire l'utilizzo delle viste con Spring 4.1, dovresti dare un'occhiata ai miglioramenti di Jackson in Spring 4.1.

7. Conclusione

In questo breve tutorial, abbiamo esaminato le viste Jackson JSON e l'annotazione @JsonView. Abbiamo mostrato come utilizzare le viste JSON per avere un controllo dettagliato sul nostro processo di serializzazione / deserializzazione, utilizzando una o più viste.

Il codice completo per questo tutorial può essere trovato su GitHub.

Jackson bottom

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO