Jackson整合及最佳实践

Jackson是一款流行的JSON序列化/反序列化工具。
官方主页:https://github.com/FasterXML/jackson,其中包含各个子模块介绍等。
当前更新的是2.x系列,稳定版为2.8.6, released 12-Jan-2017。

1. 接入

  1. Jackson系列分为三个组件:
    jackson-core:jacksonFactory的定义包,并提供最基础的序列化反序列化功能。
    jackson-annotations:支持jackson注解
    jackson-databind:提供ObjectMapper,jackson序列化/反序列化最常用的类。
  2. maven依赖:

    
      com.fasterxml.jackson.core
      jackson-core
      2.8.6
    
    
      com.fasterxml.jackson.core
      jackson-databind
      2.7.0
    
    
      com.fasterxml.jackson.core
      jackson-annotations
      2.8.6
    
    

2. 使用

  1. 利用jackson-core即可完成JSON序列化和反序列化(理论上),但使用较繁琐。
    参考链接:https://github.com/FasterXML/jackson-core
    例程:http://www.cowtowncoder.com/blog/archives/2009/01/entry_132.html
  2. 日常使用jackson-databind完成序列化和反序列化。
    官方链接:https://github.com/FasterXML/jackson-databind
    详细例程:http://blog.csdn.net/java_huashan/article/details/46375857

POJO序列化/反序列化

ObjectMapper mapper = new ObjectMapper(); // create once, reuse
//反序列化:
MyValue value = mapper.readValue(new File("data.json"), MyValue.class);
// or:
value = mapper.readValue(new URL("http://some.com/api/entry.json"), MyValue.class);
// or:
value = mapper.readValue("{\"name\":\"Bob\", \"age\":13}", MyValue.class);

//序列化:
mapper.writeValue(new File("result.json"), myResultObject);
// or:
byte[] jsonBytes = mapper.writeValueAsBytes(myResultObject);
// or:
String jsonString = mapper.writeValueAsString(myResultObject);

//集合类
Map scoreByName = mapper.readValue(jsonSource, Map.class);
List names = mapper.readValue(jsonSource, List.class);
//有自定义类
Map results = mapper.readValue(jsonSource, new TypeReference>() { } );

TreeMode

// map即ObjectNode,list即ArrayNode,两者皆可为JsonNode
// map有方法:
// set("string",variable);
// put("string",string/int);
// get("string");
// list有方法:
// add("string"/variable);

// mapper.readTree(String)从String中读出,解析为JsonNode
// mapper.writeValueAsString(JsonNode) 将JsonNode写为字符串
// mapper.writeTree(JsonGenerator, JsonNode) 将JsonNode写入生成器。生成器可由JsonFactory.createGenerator()生成,可对应Writer, File, OutputStream等。
// can be read as generic JsonNode, if it can be Object or Array; or,
// if known to be Object, as ObjectNode, if array, ArrayNode etc:
ObjectNode root = mapper.readTree("stuff.json");
String name = root.get("name").asText();
int age = root.get("age").asInt();

// can modify as well: this adds child Object as property 'other', set property 'type'
root.with("other").put("type", "student");
String json = mapper.writeValueAsString(root);

// with above, we end up with something like as 'json' String:
// {
//   "name" : "Bob", "age" : 13,
//   "other" : {
//      "type" : "student"
//   }
// }

stream API

使用率较低,编写复杂。但是效率最高。

3.常用注解与配置

  1. 常用注解:
    @JsonIgnore 此注解用于属性上,作用是进行JSON操作时忽略该属性。
    @JsonFormat 此注解用于属性上,作用是把Date类型直接转化为想要的格式,如@JsonFormat(pattern = “yyyy-MM-dd HH-mm-ss”)。
    @JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,@JsonProperty(“name”)。
  2. Mapper的一些实用配置:(其他配置可见上述jackson-databind官方链接)
// to allow serialization of "empty" POJOs (no properties to serialize)
// (without this setting, an exception is thrown in those cases)(空对象是否抛出异常)
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// to write java.util.Date, Calendar as number (timestamp):(日期改为时间戳)
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// to allow (non-standard) unquoted field names in JSON:(特殊字符和打印符,这在FastJson曾是个bug)
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// to allow use of apostrophes (single quotes), non standard(单引号)
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

4. 最佳实践

  1. JacksonFactory和ObjectMapper均为线程安全的,所以尽可能复用。(细节:ObjectMapper在被reConfigure的时候非线程安全。为了理论上的绝对安全,请使用不可变的ObjectReader/ObjectWriter。
  2. 对象使用后要清理,关闭。如JsonParser及JsonGenerator。
  3. Jackson是基于JavaBean来串行化属性的,如果属性没有GETTER方法,默认是不会输出该属性的。
5. 与FastJson

Jackson与FastJson的速度之争一直在继续。较多证据表示,在大量对象进行序列化、反序列化时,FastJson速度略胜一筹,但与Jackson差距并不大。
但是FastJson曾出现若干大bug,并引起业务故障。
例子:

遇不可打印字符的异常:于1.1.41修复。http://i.dotidea.cn/2014/08/fastjson-serialize-overflow/
远程代码执行高危安全漏洞:于1.2.28修复。https://github.com/alibaba/fastjson/wiki/security_update_20170315

相较而言,Jackson的代码质量感觉较高。在日常业务,没有大量对象的序列化需求时,推荐使用Jackson。

你可能感兴趣的:(JSON)