Vues Jackson JSON

Vues Jackson JSON

1. Vue d'ensemble

Dans ce didacticiel, nous allons expliquer 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érialiser à l'aide des vues JSON

Tout d'abord, passons par un exemple simple -serialize an object with @JsonView.

Voici notre point de vue:

public class Views {
    public static class Public {
    }
}

Et l'entité «User»:

public class User {
    public int id;

    @JsonView(Views.Public.class)
    public String name;
}

Maintenant, sérialisons une instance "User" à l'aide de 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, parce que nous sérialisons avec une vue spécifique active, nous voyonsonly the right fields being serialized.

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 pratiqueDEFAULT_VIEW_INCLUSION.

3. Utiliser 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 étendPublic, 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 champsid etname sont inclus dans la vuePublic:

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 vuePublic pour sérialiser - seuls lesid etname 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 vueInternal 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érialiser à l'aide de vues JSON

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

@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'APIreaderWithView() pour créer unObjectReader à l'aide de la vue donnée.

5. Personnaliser les vues JSON

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

Nous utiliseronsBeanPropertyWriter etBeanSerializerModifier pour personnaliser notre vue JSON. Tout d'abord, voici lesBeanPropertyWriterUpperCasingWriter pour transformer lesUsername 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 lesBeanSerializerModifier pour définir le nomUserBeanPropertyWriter avec nosUpperCasingWriter personnalisés:

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, sérialisons une instanceUser à l'aide du 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 lesSpring Framework. Nous pouvons utiliser l'annotation@JsonView pour personnaliser notre réponse JSON au niveau de l'API.

Dans l'exemple suivant, nous avons utilisé la vuePublic 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 quand nous avons utilisé la vueInternal 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 consulterthe Jackson improvements in Spring 4.1.

7. Conclusion

Dans ce rapide tutoriel, 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 de notre processus de sérialisation / désérialisation - en utilisant une ou plusieurs vues.