Автор оригинала: Eugen Paraschiv.
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 – каждое из них имеет разные поля, как в следующем примере:
Здесь мы должны посмотреть , где Внутренний расширяется Публичный , а внутренний вид расширяет публичный:
public class Views { public static class Public { } public static class Internal extends Public { } }
А вот и наша сущность ” Элемент ” , где только поля id и name включены в Public представление:
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 для десериализации объектов, в частности, экземпляра 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()); }
Обратите внимание, как мы используем reader With View() API для создания Object Reader с использованием данного представления.
5. Настройка представлений JSON
Далее – давайте посмотрим, как настроить представления JSON. В следующем примере – мы хотим сделать User ” name ” прописным в результате сериализации.
Мы будем использовать BeanPropertyWriter и BeanSerializerModifier для настройки вашего представления JSON. Во – первых-вот BeanPropertyWriter |/UpperCasingWriter для преобразования User name в верхний регистр:
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 с нашим пользовательским прописным писателем :
public class MyBeanSerializerModifier extends BeanSerializerModifier{ @Override public ListchangeProperties( 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"}
И когда мы использовали Внутренний вид следующим образом:
@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. Заключение
В этом кратком руководстве мы рассмотрели JacksonJSONviews и аннотацию @JsonView. Мы показали, как использовать представления JSON, чтобы иметь точный контроль над нашим процессом сериализации/десериализации-с использованием одного или нескольких представлений.
Полный код для этого урока можно найти на GitHub
.