«1. Обзор
В этом руководстве показано, как игнорировать определенные поля при сериализации объекта в JSON с использованием Jackson 2.x.
Это очень полезно, когда значений по умолчанию Джексона недостаточно, и нам нужно точно контролировать, что будет сериализовано в JSON — и есть несколько способов игнорировать свойства.
Если вы хотите копнуть глубже и узнать о других интересных вещах, которые можно делать с Джексоном, — переходите к основному туториалу по Джексону.
2. Игнорировать поля на уровне класса
Мы можем игнорировать определенные поля на уровне класса, используя аннотацию @JsonIgnoreProperties и указав поля по имени:
@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
}
Теперь мы можем проверить это после того, как объект записывается в JSON, поле действительно не является частью вывода:
@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. Игнорировать поле на уровне поля
Мы также можем игнорировать поле напрямую с помощью аннотации @JsonIgnore непосредственно в поле:
public class MyDto {
private String stringValue;
@JsonIgnore
private int intValue;
private boolean booleanValue;
public MyDto() {
super();
}
// standard setters and getters are not shown
}
Теперь мы можем проверить, что поле intValue действительно не является частью сериализованного вывода JSON:
@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. Игнорировать все поля по типу
Наконец, мы можем игнорировать все поля указанного type, используя аннотацию @JsonIgnoreType. Если мы контролируем тип, то можем напрямую аннотировать класс:
@JsonIgnoreType
public class SomeType { ... }
Однако чаще всего мы не контролируем сам класс; в этом случае мы можем хорошо использовать примеси Джексона.
Сначала мы определяем MixIn для типа, который мы хотели бы игнорировать, и вместо этого аннотируем его @JsonIgnoreType:
@JsonIgnoreType
public class MyMixInForIgnoreType {}
Затем мы регистрируем этот миксин для замены (и игнорирования) всех типов String[] во время маршалинг:
mapper.addMixInAnnotations(String[].class, MyMixInForIgnoreType.class);
На этом этапе все массивы String будут игнорироваться, а не маршалироваться в 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")));
}
и вот наш DTO:
public class MyDtoWithSpecialField {
private String[] stringValue;
private int intValue;
private boolean booleanValue;
}
Примечание. Начиная с версии 2.5 — кажется, что мы не можем использовать этот метод для игнорирования примитивных типов данных, но мы можем использовать его для пользовательских типов данных и массивов.
5. Игнорирование полей с помощью фильтров
Наконец, мы также можем использовать фильтры для игнорирования определенных полей в Jackson. Во-первых, нам нужно определить фильтр для объекта Java:
@JsonFilter("myFilter")
public class MyDtoWithFilter { ... }
Затем мы определяем простой фильтр, который будет игнорировать поле intValue:
SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter
.serializeAllExcept("intValue");
FilterProvider filters = new SimpleFilterProvider()
.addFilter("myFilter", theFilter);
Теперь мы можем сериализовать объект и убедиться, что Поле intValue отсутствует в выводе 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. Заключение
В статье показано, как игнорировать поля при сериализации — сначала по имени, затем напрямую и, наконец, — мы игнорировали весь java с MixIns, и мы используем фильтры для большего контроля вывода.
Реализацию всех этих примеров и фрагментов кода можно найти в моем проекте на GitHub.