Vues Jackson JSON

Haut Jackson

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS

1. Vue d'ensemble

Dans ce didacticiel, nous verrons comment utiliser les vues Jackson JSON pour sérialiser / désérialiser des objets, personnaliser les vues et enfin - comment commencer à s'intégrer à Spring.

2. Sérialisation à l'aide des vues JSON

Tout d'abord - passons par un exemple simple - sérialisez un objet avec @JsonView .

Voici notre point de vue:

public class Views { public static class Public { } }

Et l' entité « Utilisateur »:

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

Maintenant, sérialisons une instance " User " en utilisant notre vue:

@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"))); }

Notez comment, étant donné que nous sérialisons avec une vue spécifique active, nous ne voyons que les bons champs sérialisés .

Il est également important de comprendre que, par défaut, toutes les propriétés qui ne sont pas explicitement marquées comme faisant partie d'une vue sont sérialisées. Nous désactivons ce comportement avec la fonction pratique DEFAULT_VIEW_INCLUSION .

3. Utilisez plusieurs vues JSON

Ensuite - voyons comment utiliser plusieurs vues JSON - chacune a des champs différents comme dans l'exemple suivant:

Ici, nous devons voir où Internal étend Public , avec la vue interne étendant la vue publique:

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

Et voici notre entité « Item » où seuls les champs id et nom sont inclus dans la vue publique :

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

Si nous utilisons la vue publique pour sérialiser - seuls l' identifiant et le nom seront sérialisés en 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"))); }

Mais si nous utilisons la vue interne pour effectuer la sérialisation, tous les champs feront partie de la sortie 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. Désérialisation à l'aide de vues JSON

Voyons maintenant comment utiliser les vues JSON pour désérialiser des objets - en particulier, une instance User :

@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()); }

Notez comment nous utilisons l' API readerWithView () pour créer un ObjectReader en utilisant la vue donnée.

5. Personnaliser les vues JSON

Ensuite, voyons comment personnaliser les vues JSON. Dans l'exemple suivant - nous voulons que l' utilisateur « nom » UpperCase dans le résultat de la sérialisation.

Nous utiliserons BeanPropertyWriter et BeanSerializerModifier pour personnaliser notre vue JSON. Tout d'abord, voici le BeanPropertyWriter UpperCasingWriter pour transformer le nom d' utilisateur en majuscules:

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); } }

Et voici le BeanSerializerModifier pour définir le nom d' utilisateur BeanPropertyWriter avec notre UpperCasingWriter personnalisé :

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; } }

Maintenant - nous allons sérialiser un utilisateur par exemple en utilisant le sérialiseur modifié:

@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. Utilisation des vues JSON avec Spring

Enfin, jetons un coup d'œil sur l'utilisation des vues JSON avec Spring Framework . Nous pouvons tirer parti de l' annotation @JsonView pour personnaliser notre réponse JSON au niveau de l'API.

Dans l'exemple suivant, nous avons utilisé la vue publique pour répondre:

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

La réponse est:

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

Et lorsque nous avons utilisé la vue interne comme suit:

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

C'était la réponse:

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

Si vous souhaitez approfondir l'utilisation des vues avec Spring 4.1, vous devriez consulter les améliorations de Jackson dans Spring 4.1.

7. Conclusion

Dans ce didacticiel rapide, nous avons examiné les vues Jackson JSON et l'annotation @JsonView. Nous avons montré comment utiliser les vues JSON pour avoir un contrôle précis sur notre processus de sérialisation / désérialisation - en utilisant une ou plusieurs vues.

Le code complet de ce tutoriel est disponible à l'adresse over sur GitHub.

Jackson bas

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS