Перейти к основному содержимому

Джексон Просмотры JSON

· 5 мин. чтения

1. Обзор

В этом руководстве мы рассмотрим, как использовать представления Jackson JSON для сериализации/десериализации объектов, настройки представлений и, наконец, как начать интеграцию со Spring.

2. Сериализация с использованием представлений JSON

Сначала — давайте рассмотрим простой пример — сериализуйте объект с помощью @JsonView .

Вот наше мнение:

public class Views {
public static class Public {
}
}

И объект « Пользователь »:

public class User {
public int id;

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

Теперь давайте сериализуем экземпляр « User », используя наше представление:

@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")));
}

Обратите внимание, поскольку мы сериализуем с активным определенным представлением, мы видим, что сериализуются только нужные поля .

Также важно понимать, что по умолчанию все свойства, не отмеченные явным образом как часть представления, сериализуются. Мы отключаем это поведение с помощью удобной функции DEFAULT_VIEW_INCLUSION .

3. Используйте несколько представлений JSON

Далее — давайте посмотрим, как использовать несколько представлений JSON — каждое из них имеет разные поля, как в следующем примере:

Здесь у нас есть представления, где Internal расширяет Public , а внутреннее представление расширяет общедоступное:

public class Views {
public static class Public {
}

public static class Internal extends Public {
}
}

А вот и наша сущность « Item », где в публичное представление включены только поля id и name : ``

public class Item {

@JsonView(Views.Public.class)
public int id;

@JsonView(Views.Public.class)
public String itemName;

@JsonView(Views.Internal.class)
public String ownerName;
}

Если мы используем представление Public для сериализации — только id и имя будут сериализованы в 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")));
}

Но если мы используем внутреннее представление для выполнения сериализации, все поля будут частью вывода 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. Десериализация с использованием представлений JSON

Теперь давайте посмотрим, как использовать представления JSON для десериализации объектов, в частности, экземпляра пользователя :

@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());
}

Обратите внимание, как мы используем API-интерфейс readerWithView() для создания ObjectReader с использованием данного представления.

5. Настройте представления JSON

Далее — давайте посмотрим, как настроить представления JSON. В следующем примере мы хотим сделать User « имя » UpperCase в результате сериализации.

Мы будем использовать BeanPropertyWriter и BeanSerializerModifier для настройки представления JSON. Во-первых, вот BeanPropertyWriter UpperCasingWriter для преобразования имени пользователя в верхний регистр: ``

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);
}
}

А вот BeanSerializerModifier для установки имени пользователя BeanPropertyWriter с помощью нашего пользовательского UpperCasingWriter :

public class MyBeanSerializerModifier extends BeanSerializerModifier{

@Override
public List<BeanPropertyWriter> changeProperties(
SerializationConfig config, BeanDescription beanDesc,
List<BeanPropertyWriter> 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;
}
}

Теперь давайте сериализуем экземпляр User , используя модифицированный Serializer:

@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. Использование представлений JSON с Spring

Наконец — давайте кратко рассмотрим использование представлений JSON с Spring Framework . Мы можем использовать аннотацию @JsonView для настройки нашего ответа JSON на уровне API.

В следующем примере мы использовали представление Public для ответа:

@JsonView(Views.Public.class)
@RequestMapping("/items/{id}")
public Item getItemPublic(@PathVariable int id) {
return ItemManager.getById(id);
}

Ответ:

{"id":2,"itemName":"book"}

И когда мы использовали внутренний вид следующим образом:

@JsonView(Views.Internal.class)
@RequestMapping("/items/internal/{id}")
public Item getItemInternal(@PathVariable int id) {
return ItemManager.getById(id);
}

Это был ответ:

{"id":2,"itemName":"book","ownerName":"John"}

Если вы хотите глубже погрузиться в использование представлений в Spring 4.1, вам следует ознакомиться с улучшениями Джексона в Spring 4.1 .

7. Заключение

В этом кратком руководстве мы рассмотрели представления Jackson JSON и аннотацию @JsonView. Мы показали, как использовать представления JSON для детального контроля над нашим процессом сериализации/десериализации — с использованием одного или нескольких представлений.

Полный код этого руководства можно найти на GitHub .