Джексон JSON Просмотров
1. обзор
В этом руководстве мы рассмотрим, как использовать представления Jackson JSON Views для сериализации / десериализации объектов, настройки представлений и, наконец, как начать интеграцию со Spring.
2. Сериализация с использованием представлений JSON
Сначала рассмотрим простой пример -serialize an object with @JsonView.
Вот наш взгляд:
public class Views {
public static class Public {
}
}
И сущность «User»:
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")));
}
Обратите внимание: поскольку мы сериализуем с конкретным активным представлением, мы видимonly the right fields being serialized.
Также важно понимать, что по умолчанию все свойства, явно не отмеченные как часть представления, сериализуются. Мы отключаем это поведение с помощью удобной функцииDEFAULT_VIEW_INCLUSION.
3. Используйте несколько представлений JSON
Далее - давайте посмотрим, как использовать несколько представлений JSON, каждое из которых имеет разные поля, как в следующем примере:
Здесь нам нужно просмотреть, гдеInternal расширяетPublic, а внутреннее представление расширяет общедоступное:
public class Views {
public static class Public {
}
public static class Internal extends Public {
}
}
А вот наша сущность «Item», где в представлениеPublic включены только поля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 иname будут сериализованы в 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")));
}
Но если мы используем представлениеInternal для выполнения сериализации, все поля будут частью вывода 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 Views для десериализации объектов, в частности экземпляраUser:
@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());
}
Обратите внимание, как мы используем APIreaderWithView() для созданияObjectReader с использованием данного представления.
5. Настроить представления JSON
Далее - давайте посмотрим, как настроить представления JSON. В следующем примере мы хотим сделатьUser «name» верхним регистром в результате сериализации.
Мы будем использоватьBeanPropertyWriter иBeanSerializerModifier для настройки нашего представления JSON. Во-первых - вотBeanPropertyWriterUpperCasingWriter для преобразованияUsername в верхний регистр:
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 для установки имениUserBeanPropertyWriter с нашим пользовательскимUpperCasingWriter:
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;
}
}
Теперь - давайте сериализуем экземплярUser с помощью модифицированного сериализатора:
@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"}
И когда мы использовали представлениеInternal следующим образом:
@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, вам следует проверитьthe Jackson improvements in Spring 4.1.
7. Заключение
В этом быстром уроке мы взглянули на JSON-представления Джексона и аннотацию @JsonView. Мы показали, как использовать JSON Views, чтобы получить детальный контроль над процессом сериализации / десериализации - используя одно или несколько представлений.