Jackson ignora propriedades em Marshalling

Jackson ignora propriedades em Marshalling

1. Visão geral

Este tutorial mostrará comoignore certain fields when serializing an object to JSON usando Jackson 2.x.

Isso é muito útil quando os padrões de Jackson não são suficientes e precisamos controlar exatamente o que é serializado para JSON - e há várias maneiras de ignorar as propriedades.

Se você quiser se aprofundar e aprender outras coisas legais que você pode fazer com o Jackson - vá parathe main Jackson tutorial.

Leitura adicional:

Introdução ao Jackson ObjectMapper

O artigo discute a classe ObjectMapper central de Jackson, a serialização e desserialização básicas, bem como a configuração dos dois processos.

Read more →

API de streaming de Jackson

Uma visão geral rápida da API de streaming de Jackson para processamento de JSON, incluindo os exemplos

Read more →

Guia de @JsonFormat em Jackson

Um guia rápido e prático para a anotação @JsonFormat em Jackson.

Read more →

2. Ignorar campos no nível da classe

Podemos ignorar campos específicos no nível da classe, usandothe @JsonIgnoreProperties annotation and specifying the fields by name:

@JsonIgnoreProperties(value = { "intValue" })
public class MyDto {

    private String stringValue;
    private int intValue;
    private boolean booleanValue;

    public MyDto() {
        super();
    }

    // standard setters and getters are not shown
}

Agora podemos testar que, depois que o objeto é gravado em JSON, o campo não faz parte da saída:

@Test
public void givenFieldIsIgnoredByName_whenDtoIsSerialized_thenCorrect()
  throws JsonParseException, IOException {

    ObjectMapper mapper = new ObjectMapper();
    MyDto dtoObject = new MyDto();

    String dtoAsString = mapper.writeValueAsString(dtoObject);

    assertThat(dtoAsString, not(containsString("intValue")));
}

3. Ignorar campo no nível do campo

Também podemos ignorar um campo diretamente viathe @JsonIgnore annotation directly on the field:

public class MyDto {

    private String stringValue;
    @JsonIgnore
    private int intValue;
    private boolean booleanValue;

    public MyDto() {
        super();
    }

    // standard setters and getters are not shown
}

Agora podemos testar se o campointValue realmente não faz parte da saída JSON serializada:

@Test
public void givenFieldIsIgnoredDirectly_whenDtoIsSerialized_thenCorrect()
  throws JsonParseException, IOException {

    ObjectMapper mapper = new ObjectMapper();
    MyDto dtoObject = new MyDto();

    String dtoAsString = mapper.writeValueAsString(dtoObject);

    assertThat(dtoAsString, not(containsString("intValue")));
}

4. Ignorar todos os campos por tipo

Finalmente, podemosignore all fields of a specified type, using the @JsonIgnoreType annotation. Se controlarmos o tipo, podemos anotar a classe diretamente:

@JsonIgnoreType
public class SomeType { ... }

Na maioria das vezes, no entanto, não temos controle da própria classe; neste caso,we can make good use of Jackson mixins.

Primeiro, definimos um MixIn para o tipo que gostaríamos de ignorar e anotamos com@JsonIgnoreType ao invés:

@JsonIgnoreType
public class MyMixInForIgnoreType {}

Em seguida, registramos esse mixin para substituir (e ignorar) todos os tiposString[] durante o empacotamento:

mapper.addMixInAnnotations(String[].class, MyMixInForIgnoreType.class);

Neste ponto, todas as matrizes String serão ignoradas em vez de empacotadas para JSON:

@Test
public final void givenFieldTypeIsIgnored_whenDtoIsSerialized_thenCorrect()
  throws JsonParseException, IOException {

    ObjectMapper mapper = new ObjectMapper();
    mapper.addMixIn(String[].class, MyMixInForIgnoreType.class);
    MyDtoWithSpecialField dtoObject = new MyDtoWithSpecialField();
    dtoObject.setBooleanValue(true);

    String dtoAsString = mapper.writeValueAsString(dtoObject);

    assertThat(dtoAsString, containsString("intValue"));
    assertThat(dtoAsString, containsString("booleanValue"));
    assertThat(dtoAsString, not(containsString("stringValue")));
}

e aqui está o nosso DTO:

public class MyDtoWithSpecialField {
    private String[] stringValue;
    private int intValue;
    private boolean booleanValue;
}

Nota: Desde a versão 2.5 - parece que não podemos usar esse método para ignorar tipos de dados primitivos, mas podemos usá-lo para tipos e matrizes de dados personalizados.

5. Ignorar campos usando filtros

Finalmente,we can also use filters to ignore specific fields em Jackson. Primeiro, precisamos definir o filtro no objeto Java:

@JsonFilter("myFilter")
public class MyDtoWithFilter { ... }

Então, definimos um filtro simples que irá ignorar o campointValue:

SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter
  .serializeAllExcept("intValue");
FilterProvider filters = new SimpleFilterProvider()
  .addFilter("myFilter", theFilter);

Agora podemos serializar o objeto e garantir que o campointValue não esteja presente na saída JSON:

@Test
public final void givenTypeHasFilterThatIgnoresFieldByName_whenDtoIsSerialized_thenCorrect()
  throws JsonParseException, IOException {

    ObjectMapper mapper = new ObjectMapper();
    SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter
      .serializeAllExcept("intValue");
    FilterProvider filters = new SimpleFilterProvider()
      .addFilter("myFilter", theFilter);

    MyDtoWithFilter dtoObject = new MyDtoWithFilter();
    String dtoAsString = mapper.writer(filters).writeValueAsString(dtoObject);

    assertThat(dtoAsString, not(containsString("intValue")));
    assertThat(dtoAsString, containsString("booleanValue"));
    assertThat(dtoAsString, containsString("stringValue"));
    System.out.println(dtoAsString);
}

6. Conclusão

O artigo ilustrou como ignorar os campos na serialização - primeiro pelo nome, depois diretamente e finalmente - ignoramos todo o tipo de java com o MixIns e usamos filtros para maior controle da saída.

A implementação de todos esses exemplos e trechos de código pode ser encontrada emmy GitHub project.