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.