Jackson JSON Views – 杰克逊JSON视图

最后修改: 2014年 12月 13日

1. Overview

1.概述

In this tutorial, we’ll go over how to use Jackson JSON Views to serialize/deserialize objects, customize the views and finally – how to start integrating with Spring.

在本教程中,我们将讨论如何使用Jackson JSON视图来序列化/反序列化对象,自定义视图,最后–如何开始与Spring集成。

2. Serialize Using JSON Views

2.使用JSON视图进行序列化

First – let’s go through a simple example – serialize an object with @JsonView.

首先–让我们通过一个简单的例子–@JsonView序列化一个对象。

Here is our view:

以下是我们的观点。

public class Views {
    public static class Public {
    }
}

And the “User” entity:

还有”User“实体。

public class User {
    public int id;

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

Now let’s serialize a “User” instance using our view:

现在让我们使用我们的视图来序列化一个”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")));
}

Note how, because we’re serializing with a specific view active, we’re seeing only the right fields being serialized.

请注意,由于我们是在特定视图激活的情况下进行序列化,我们看到只有正确的字段被序列化

It’s also important to understand, that – by default – all properties not explicitly marked as being part of a view, are serialized. We are disabling that behavior with the handy DEFAULT_VIEW_INCLUSION feature.

同样重要的是要理解,默认情况下,所有没有明确标记为视图一部分的属性都被序列化了。我们用方便的DEFAULT_VIEW_INCLUSION特性来禁用这种行为。

3. Use Multiple JSON Views

3.使用多个JSON视图

Next – let’s see how to use multiple JSON Views – each has different fields as in the following example:

接下来–让我们看看如何使用多个JSON视图–每个视图都有不同的字段,如下例所示。

Here we have to views where Internal extends Public, with the internal view extending the public one:

这里我们有一些视图,其中Internal扩展了Public,内部视图扩展了公共视图。

public class Views {
    public static class Public {
    }

    public static class Internal extends Public {
    }
}

And here is our entity “Item” where only the fields id and name are included in the Public view:

这里是我们的实体”Item“,其中只有字段idname被包含在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;
}

If we use the Public view to serialize – only id and name will be serialized to JSON:

如果我们使用Public视图来序列化–只有idname将被序列化为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")));
}

But if we use the Internal view to perform the serialization, all fields will be part of the JSON output:

但如果我们使用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. Deserialize Using JSON Views

4.使用JSON视图进行反序列化

Now – let’s see how to use JSON Views to deserialize objects – specifically, a User instance:

现在–让我们看看如何使用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());
}

Note how we’re using the readerWithView() API to create an ObjectReader using the given view.

注意我们是如何使用readerWithView() API来创建一个使用给定视图的ObjectReader

5. Customize JSON Views

5.自定义JSON视图</strong

Next – let’s see how to customize JSON Views. In the next example – we want to make the Username” UpperCase in the serialization result.

接下来 – 让我们看看如何定制JSON视图。在下一个例子中–我们想让序列化结果中的Username” 大写。

We will use BeanPropertyWriter and BeanSerializerModifier to customize our JSON view. First – here is the BeanPropertyWriter UpperCasingWriter to transform the User name to upper case:

我们将使用BeanPropertyWriterBeanSerializerModifier来定制我们的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);
    }
}

And here is the BeanSerializerModifier to set the User name BeanPropertyWriter with our custom UpperCasingWriter:

这里是BeanSerializerModifier,用我们自定义的UpperCasingWriter来设置UserBeanPropertyWriter

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

Now – let’s serialize a User instance using the modified Serializer:

现在–让我们使用修改后的序列化器来序列化一个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. Using JSON Views With Spring

6.使用Spring的JSON视图

Finally – let’s take a quick look at using JSON views with the Spring Framework. We can leverage the @JsonView annotation to customize our JSON response at the API level.

最后,让我们快速了解一下使用JSON视图与Spring Framework的情况。我们可以利用@JsonView注解,在API层面定制我们的JSON响应。

In the following example – we used the Public view to respond:

在下面的例子中–我们使用Public视图来回应。

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

The response is:

答复是。

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

And when we used the Internal view as follows:

而当我们使用Internal视图时,如下所示。

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

That was the response:

这就是回应。

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

If you want to dive deeper into using the views with Spring 4.1, you should check out the Jackson improvements in Spring 4.1.

如果您想更深入地了解使用Spring 4.1的视图,您应该查看Spring 4.1中的Jackson改进

7. Conclusion

7.结论

In this quick tutorial, we had a look at the Jackson JSON views and the @JsonView annotation. We showed how to use JSON Views to have fine-grained control over our serialize/deserialize process – using a single or multiple views.
The complete code for this tutorial can be found over on GitHub.

在这个快速教程中,我们看了一下Jackson的JSON视图和@JsonView注解。我们展示了如何使用JSON视图来对我们的序列化/反序列化过程进行细粒度的控制–使用单个或多个视图。
本教程的完整代码可在 GitHub 上找到