Android 基本 Jackson Marshalling/Unmarshalling

本文内容

  • 基本 Jack Marshalling
    • 忽略属性
    • 忽略 Null 字段
    • 改变字段名字
  • 基本 Jackson Marshalling
    • 把 JSON 解析成 JsonNode
    • 带无法识别的属性的 Unmarshalling json
  • 参考资料
  • 术语

 

基本 Jackson Marshalling


如何把一个 Java 实体序列化(serialize)成一个 JSON 字符串,并且如何控制映射的过程,以便达到准确的你想要的 JSON 格式。

忽略属性

当 Jackson 默认值不够,我们就需要准确地控制序列化什么成 JSON,此时非常有用。有很多方式来忽略属性。

  • 在类的级别上忽略字段(field)

通过使用 @JsonIgnoreProperties 注解(annotation)和指定字段名字,我们可以在类的级别上忽略指定的字段:

@JsonIgnoreProperties(value = { "intValue" })
public class MyDto {
 
    private String stringValue;
    private int intValue;
    private boolean booleanValue;
 
    public MyDto() {
        super();
    }
 
    // standard setters and getters are not shown
}

现在测试一下,对象被写成 JSON 后,intValue 字段没有输出:

@Test
public void givenFieldIsIgnoredByName_whenDtoIsSerialized_thenCorrect()
  throws JsonParseException, IOException {
    ObjectMapper mapper = new ObjectMapper();
    MyDto dtoObject = new MyDto();
 
    String dtoAsString = mapper.writeValueAsString(dtoObject);
 
    assertThat(dtoAsString, not(containsString("intValue")));
}
  • 在字段的级别上忽略字段

We can also ignore a field directly via the @JsonIgnore annotation directly on the field:

public class MyDto {
 
    private String stringValue;
    @JsonIgnore
    private int intValue;
    private boolean booleanValue;
 
    public MyDto() {
        super();
    }
 
    // standard setters and getters are not shown
}

We can now test that the intValue field is indeed not part of the serialized json output:

@Test
public void givenFieldIsIgnoredDirectly_whenDtoIsSerialized_thenCorrect()
  throws JsonParseException, IOException {
    ObjectMapper mapper = new ObjectMapper();
    MyDto dtoObject = new MyDto();
 
    String dtoAsString = mapper.writeValueAsString(dtoObject);
 
    assertThat(dtoAsString, not(containsString("intValue")));
}
  • Ignore all fields by type

Finally, we can ignore all fields of a specified type, using the @JsonIgnoreType anotation. If we control the type, then we can annotate the class directly:

@JsonIgnoreType
public class SomeType { ... }

More often than not however, we don’t have control of the class itself; in this case, we can make good use of Jackson mixins.

First, we define a MixIn for the type we’d like to ignore, and annotate that with @JsonIgnoreType instead:

@JsonIgnoreType
public class MyMixInForString {
    //
}

Then we register that mixin to replace (and ignore) all String types during marshalling:

mapper.addMixInAnnotations(String.class, MyMixInForString.class);

At this point, all Strings will be ignored instead of marshalled to json:

@Test
public final void givenFieldTypeIsIgnored_whenDtoIsSerialized_thenCorrect()
  throws JsonParseException, IOException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.addMixInAnnotations(String.class, MyMixInForString.class);
    MyDto dtoObject = new MyDto();
    dtoObject.setBooleanValue(true);
 
    String dtoAsString = mapper.writeValueAsString(dtoObject);
 
    assertThat(dtoAsString, containsString("intValue"));
    assertThat(dtoAsString, containsString("booleanValue"));
    assertThat(dtoAsString, not(containsString("stringValue")));
}
  • Ignore fields using Filters

Finally, we can also use Filters to ignore specific fields in Jackson. First, we need to define the filter on the java object:

@JsonFilter("myFilter")
public class MyDtoWithFilter { ... }

Then, we define a simple filter that will ignore the intValue field:

SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter.serializeAllExcept("intValue");
FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", theFilter);

Now we can serialize the object and make sure that the intValue field is not present in the json output:

@Test
public final void givenTypeHasFilterThatIgnoresFieldByName_whenDtoIsSerialized_thenCorrect()
  throws JsonParseException, IOException {
    ObjectMapper mapper = new ObjectMapper();
    SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter.serializeAllExcept("intValue");
    FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", theFilter);
 
    MyDtoWithFilter dtoObject = new MyDtoWithFilter();
    String dtoAsString = mapper.writer(filters).writeValueAsString(dtoObject);
 
    assertThat(dtoAsString, not(containsString("intValue")));
    assertThat(dtoAsString, containsString("booleanValue"));
    assertThat(dtoAsString, containsString("stringValue"));
    System.out.println(dtoAsString);
}

he article illustrated how to ignore fields on serialization – first by name, then directly, and finally – we ignored the entire java type with MixIns and we use filters for more control of the output.

The implementation of all these examples and code snippets can be found in my github project – this is an Eclipse based project, so it should be easy to import and run as it is.

 

忽略 Null 字段

改变字段名字

 

基本 Jackson Unmarshalling


说明如何把一个 JSON 字符串反序列(deserialize)化成一个 Java 实体。无论 JSON 多么“怪异”,我们需要把它映射成一个已定义的 Java 实体类。

把 JSON 解析成 JsonNode

带未识别属性的 Unmarshalling json

 

参考资料


 

术语


Marshalling/Unmarshalling

marshalling 是把一个对象的内存描述转换成适合存储或传输的一个数据格式的过程,它通常用于,数据必须在一个计算机程序的不同部分之间,从一个程序移动到另一个。Marshalling 类似于 serialization,用于一个对象跟远程对象通信,在这种情况下,是一个被序列化的对象。这简化了复杂的通信,使用自定义、复杂的对象通信,而不是基本数据类型。与 marshalling 相对的,或逆过程,称为 unmarshalling(demarshalling,类似于 deserialization)。

在 Python 里,marshal 跟 serialize 是一个概念,但是在 Java 中却不是。

参看 http://en.wikipedia.org/wiki/Unmarshalling#Comparison_with_serialization

Android 基本 Jackson Marshalling/Unmarshalling,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。