杰克逊JSON的观点
最后修改:2020年2月12日
1.概述
在本教程中,我们将介绍如何使用Jackson JSON视图序列化/反序列化对象,自定义视图,最后介绍如何开始与Spring集成。
2.使用JSON视图序列化
首先,我们来看一个简单的例子序列化一个对象@JsonView。
以下是我们的观点:
public class视图{public static class public {}}
和“用户“实体:
public class User {public int id;@JsonView(Views.Public.class) public String name;}
现在让我们序列化a "用户实例使用我们的视图:
@Test public void whenusejsonviewtoserialize_threct () throws JsonProcessingException{用户用户=新用户(1,“约翰”);ObjectMapper = new ObjectMapper();mapper.disable (MapperFeature.DEFAULT_VIEW_INCLUSION);String result = mapper .writerWithView(Views.Public.class) .writeValueAsString(user);为了(因此,containsString(“约翰”));为了(结果,而不是(containsString (" 1 ")));}
请注意,因为我们正在用一个特定的活动视图进行序列化,所以我们看到只有正确的字段被序列化。
在默认情况下,所有未显式标记为视图一部分的属性都被序列化,理解这一点也很重要。我们用方便的工具来禁用这种行为DEFAULT_VIEW_INCLUSION特性。
3.使用多个JSON视图
接下来,让我们看看如何使用多个JSON视图,每个JSON视图都有不同的字段,如下例所示:
这里我们有视图内部扩展公共,以内部视角延伸公众视角:
public class view {public static class {} public static class内部扩展public {}}
这就是我们的实体"项“那里只有田野id和的名字均包括在公共观点:
public class Item {@JsonView(Views.Public.class) public int id;@JsonView(Views.Public.class) public String itemName;@JsonView(Views.Internal.class) public String ownerName;}
如果我们使用公共只能序列化的视图id和的名字将被序列化为JSON:
@Test public void whenUsePublicView_thenOnlyPublicSerialized() throws JsonProcessingException {Item Item = new Item(2,“书”,“约翰”);ObjectMapper = new ObjectMapper();String result = mapper .writerWithView(Views.Public.class) .writeValueAsString(item);为了(因此,containsString(“书”));为了(因此,containsString(“2”));为了(结果,而不是(containsString(“约翰”)));}
但是如果我们用内部视图执行序列化,所有字段将是JSON输出的一部分:
@Test public void whenUseInternalView_thenAllSerialized() throws JsonProcessingException {Item Item = new Item(2,“书”,“约翰”);ObjectMapper = new ObjectMapper();String result = mapper .writerWithView(Views.Internal.class) .writeValueAsString(item);为了(因此,containsString(“书”));为了(因此,containsString(“2”));为了(因此,containsString(“约翰”));}
4.使用JSON视图反序列化
现在-让我们看看如何使用JSON视图来反序列化对象-具体来说,a用户实例:
@Test public void whenusejsonviewtodeserialize_thorrect () throws IOException {String json = "{"id":1,"name":"John"}";ObjectMapper = new ObjectMapper();User User = mapper .readerWithView(Views.Public.class) .forType(User.class) .readValue(json);assertequal (user.getId ());assertequal(“约翰”,user.getName ());}
注意我们是如何使用readerWithView ()API创建ObjectReader使用给定的视图。
5.自定义JSON的观点
接下来,让我们看看如何定制JSON视图。在下一个例子中,我们想要用户”的名字"序列化结果中的大写。
我们将使用BeanPropertyWriter和BeanSerializerModifier定制我们的JSON视图。首先,这是BeanPropertyWriterUpperCasingWriter来转换用户的名字大写:
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(“名字”,价值);}}
这是BeanSerializerModifier设置用户的名字BeanPropertyWriter与我们的习俗UpperCasingWriter:
public class MyBeanSerializerModifier extends BeanSerializerModifier{@Override public List changeProperties(SerializationConfig config, BeanDescription beanDesc, List beanProperties) {for (int i = 0;我< beanProperties.size ();i++) {BeanPropertyWriter writer = beanProperties.get(i);if (writer.getName() == "name") {beanProperties. getname ();集(我,新的UpperCasingWriter(作家));}}返回beanProperties;}}
现在,让我们序列化a用户使用修改过的Serializer的实例:
@Test public void whenusecustomjsonviewtoserialize_threct () throws JsonProcessingException{用户用户=新用户(1,“约翰”);SerializerFactory = BeanSerializerFactory。实例.withSerializerModifier(新MyBeanSerializerModifier ());ObjectMapper = new ObjectMapper();mapper.setSerializerFactory (serializerFactory);String result = mapper .writerWithView(Views.Public.class) .writeValueAsString(user);为了(因此,containsString(“约翰”));为了(因此,containsString (" 1 "));}
6.使用JSON视图与Spring
最后,让我们快速了解一下如何使用JSON视图Spring框架。我们可以利用@JsonView注释来在API级别定制我们的JSON响应。
在下面的例子中,我们使用公共为了回应:
@JsonView(Views.Public.class) @RequestMapping("/items/{id}") public Item getItemPublic(@PathVariable int id) {return ItemManager.getById(id);}
的反应是:
{" id ": 2,“itemName”:“书”}
当我们用内部视图如下:
@JsonView(view . internal .class) @RequestMapping("/items/internal/{id}") public Item getItemInternal(@PathVariable int id) {return ItemManager.getById(id);}
这是他们的回应:
{" id ": 2,“itemName”:“书”,“ownerName”:“约翰”}
如果您想更深入地使用Spring 4.1中的视图,您应该检查一下Spring 4.1中的Jackson改进。
7.结论
在本快速教程中,我们了解了Jackson JSON视图和@JsonView注释。我们展示了如何使用JSON视图对序列化/反序列化过程进行细粒度控制——使用单个或多个视图。
可以找到本教程的完整代码在GitHub。