Visualizações JSON de Jackson
1. Visão geral
Neste tutorial, veremos como usar Jackson JSON Views para serializar / desserializar objetos, personalizar as visualizações e, finalmente, como começar a integração com Spring.
2. Serializar usando visualizações JSON
Primeiro - vamos ver um exemplo simples -serialize an object with @JsonView.
Aqui está a nossa visão:
public class Views {
public static class Public {
}
}
E a entidade “User”:
public class User {
public int id;
@JsonView(Views.Public.class)
public String name;
}
Agora vamos serializar uma instância “User” usando nossa visão:
@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")));
}
Observe como, porque estamos serializando com uma vista específica ativa, estamos vendoonly the right fields being serialized.
Também é importante entender que - por padrão - todas as propriedades não marcadas explicitamente como parte de uma visualização são serializadas. Estamos desativando esse comportamento com o útil recursoDEFAULT_VIEW_INCLUSION.
3. Use várias visualizações JSON
A seguir - vamos ver como usar várias visualizações JSON - cada uma tem campos diferentes, como no exemplo a seguir:
Aqui temos as visualizações ondeInternal estendePublic, com a visualização interna estendendo a pública:
public class Views {
public static class Public {
}
public static class Internal extends Public {
}
}
E aqui está nossa entidade “Item”, onde apenas os camposidename estão incluídos na visualizaçãoPublic:
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 usarmos a visualizaçãoPublic para serializar - apenasidename serão serializados para 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")));
}
Mas se usarmos a visualizaçãoInternal para realizar a serialização, todos os campos farão parte da saída 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. Desserializar usando visualizações JSON
Agora - vamos ver como usar visualizações JSON para desserializar objetos - especificamente, uma instânciaUser:
@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());
}
Observe como estamos usando a APIreaderWithView() para criar umObjectReader usando a visualização fornecida.
5. Personalizar visualizações JSON
A seguir - vamos ver como personalizar visualizações JSON. No próximo exemplo - queremos fazerUser “name” UpperCase no resultado da serialização.
UsaremosBeanPropertyWritereBeanSerializerModifier para personalizar nossa visualização JSON. Primeiro - aqui está oBeanPropertyWriterUpperCasingWriter para transformarUsername em maiúsculas:
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);
}
}
E aqui está oBeanSerializerModifier para definir o nomeUserBeanPropertyWriter com nossoUpperCasingWriter personalizado:
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;
}
}
Agora - vamos serializar uma instânciaUser usando o Serializer modificado:
@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. Usando visualizações JSON com Spring
Finalmente - vamos dar uma olhada rápida no uso de visualizações JSON comSpring Framework. Podemos aproveitar a anotação@JsonView para personalizar nossa resposta JSON no nível da API.
No exemplo a seguir - usamos a visualizaçãoPublic para responder:
@JsonView(Views.Public.class)
@RequestMapping("/items/{id}")
public Item getItemPublic(@PathVariable int id) {
return ItemManager.getById(id);
}
A resposta é:
{"id":2,"itemName":"book"}
E quando usamos a visualizaçãoInternal da seguinte maneira:
@JsonView(Views.Internal.class)
@RequestMapping("/items/internal/{id}")
public Item getItemInternal(@PathVariable int id) {
return ItemManager.getById(id);
}
Essa foi a resposta:
{"id":2,"itemName":"book","ownerName":"John"}
Se você quiser se aprofundar no uso das visualizações com Spring 4.1, você deve verificarthe Jackson improvements in Spring 4.1.
7. Conclusão
Neste tutorial rápido, vimos as visualizações Jackson JSON e a anotação @JsonView. Mostramos como usar as visualizações JSON para ter um controle refinado sobre nosso processo de serialização / desserialização - usando uma ou várias visualizações.