杰克逊顶部

通过。开始使用Spring 5和Spring Boot 2学习的春天课程:

>>查看课程

1.概述

本教程将演示我们如何做到如果某个字段满足特定的、自定义的条件,则使用Jackson来序列化该字段

例如,假设我们只想序列化一个正的整数值——如果它不是正的,我们想完全跳过它。

如果你想深入挖掘和学习你还可以用杰克逊2做其他很酷的事情-去主要的杰克逊教程

2.使用Jackson过滤器来控制序列化过程

首先,我们需要在实体上定义过滤器,使用@jsonfilter.注释:

@jsonfilter(“myfilter”)公共课程MyDto {私人int Intvalue;公共mydto(){super();public int getIntvalue(){返回Intvalue;}公共void setIntValue(int Intvalue){this.intvalue = Intvalue;}}

然后,我们需要定义自定义Processfilter.:

public void serializeAsField (Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer) throws Exception {if (include(writer)) {if (!writer. getname ().equals("intValue")) {serializeAsField (pojo, jgen提供者);返回;} int intValue = ((MyDtoWithFilter) pojo). gettintvalue ();if (intValue >= 0){写入。serializeAsField (pojo, jgen提供者);}} else if (!jgen.canOmitFields()){//自2.3写入。serializeAsOmittedField (pojo, jgen提供者);}} @Override protected boolean include(BeanPropertyWriter writer){返回true;} @Override protected boolean include(PropertyWriter写入器){返回true;}};

这个过滤器包含决定是否Intvalue.领域将是序列化或不,基于其价值。

接下来,我们将这个过滤器挂接到ObjectMapper.我们序列化实体:

filter = new SimpleFilterProvider()。addFilter(“myFilter”,theFilter);MyDto dtoObject = new MyDto();dtoObject.setIntValue (1);objectapper mapper = new objectapper ();dtoAsString = mapper.writer(filters).writeValueAsString(dtoObject);

最后,我们可以验证Intvalue.场确实是不是编组的JSON输出的一部分:

为了(dtoAsString,而不是(containsString(“intValue”)));

3.跳过对象条件

现在,让我们讨论一下在基于属性进行序列化时如何跳过对象价值。我们将跳过所有对象的属性真的:

3.1。弥漫的课程

首先,让我们看看我们的弥漫界面:

@jsonignoreproperties(“hidden”)公共界面隐藏{boolean ishidden();}

我们有两个简单的类实现此界面,地址:

班级:

public class Person implements Hidable {private String name;私有地址地址;私人布尔隐藏;}

地址班级:

公共班级地址实施隐士{私有弦城市;私人串国家;私人布尔隐藏;}

注意:我们使用@jsonignoreproperties(“隐藏”)以确保财产本身不包括在JSON中

3.2。自定义序列化器

接下来——这是我们的自定义序列化器:

public class HidableSerializer extends JsonSerializer {private JsonSerializer defaultSerializer;public HidableSerializer(JsonSerializer serializer) {defaultSerializer = serializer;} public void serialize(Hidable value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {if (value. ishidden ()) return;defaultSerializer。序列化(价值、jgen提供者);} @Override public boolean isEmpty(SerializerProvider provider,隐藏值){return (value == null || value. ishidden ());}}
         

注意:

  • 当对象不会被跳过时,我们将序列化委托给默认注入的序列化器。
  • 我们重写了这个方法isEmpty ()- 要确保在隐藏对象的情况下,也可以从JSON中排除属性名称。

3.3。使用BeanSerializerModifier

最后,我们将需要使用BeanSerializerModifier在我们的自定义中注入默认的序列化器HidableSerializer- 如下:

objectapper mapper = new objectapper ();Mapper.SetSerializationInclusion(包括.NON_EMPTY);mapper.registerermodule(新simpleModule(){@override public void setupmodule(setupcontext context){super.setupmodule(上下文); context.addbeanserializermodifier(新beanserializermodifier(){@override public jsonserializer <?> modifyserializer(serializationconfig config,beandescription desc,JSonserializer <?>序列化器){if(hidable.class.isassignable from(desc.getbeanclass())){return new hidableserializer((jsonserializer )序列化程序);} return serializer;}};}});
         

3.4。示例输出

下面是一个简单的序列化例子:

地址AD1 =新地址(“TOKYO”,“JP”,TRUE);地址AD2 =新地址(“伦敦”,“英国”,假);地址AD3 =新地址(“NY”,“USA”,FALSE);人P1 =新人(“约翰”,AD1,FALSE);人p2 =新人(“汤姆”,ad2,true);人P3 =新人(“亚当”,AD3,FALSE);system.out.println(mapper.writevalueastring(arrays.aslist(p1,p2,p3)))));

并且输出是:

[{“姓名”:“John”},{“姓名”:“亚当”,“地址”:{“城市”:“NY”,“国家”:“USA”}}]

3.5。测试

最后 - 这几个测试用例:

第一次案例,没有隐藏:

@Test public void whennothidden_thencright () throws JsonProcessingException {Address ad = new Address("ny", "usa", false);Person Person = new Person("john", ad, false);String result = mapper.writeValueAsString(person);assertTrue (result.contains("名称"));assertTrue (result.contains(“约翰”));assertTrue (result.contains(“地址”);assertTrue (result.contains(“美国”));}

接下来,只有地址是隐藏的:

@Test public void whenaddresshidden_thcorrect () throws JsonProcessingException {Address ad = new Address("ny", "usa", true);Person Person = new Person("john", ad, false);String result = mapper.writeValueAsString(person);assertTrue (result.contains("名称"));assertTrue (result.contains(“约翰”));assertFalse (result.contains(“地址”);assertFalse (result.contains(“美国”));}

现在,整个人都隐藏起来了:

@test public void whenallhidden_​​thencorrect()抛出jsonprocessingexception {地址广告=新地址(“ny”,“美国”,false);人员=新人(“约翰”,广告,真实);String result = mapper.writeValueAsString(person);asserttrue(结果.Length()== 0);}

4.结论

这种高级过滤功能非常强大,当使用Jackson序列化复杂对象时,可以非常灵活地定制json。

更灵活但更复杂的替代方案将使用完全自定义的串行器来控制JSON输出 - 因此,如果此解决方案足够灵活,则可能值得探讨这一点。

实现所有这些示例和代码片段可以找到在github上- 它是一个基于Maven的项目,因此应该易于导入和运行。

杰克逊底部

通过。开始使用Spring 5和Spring Boot 2学习的春天课程:

>>查看课程
13注释
最老的
最新
内联反馈
查看所有评论
评论在本文上关闭!