Jackson整合及最佳实践

来源:互联网 发布:华讯网络 怎么样 编辑:程序博客网 时间:2024/06/05 17:09

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依赖:

    <dependency>  <groupId>com.fasterxml.jackson.core</groupId>  <artifactId>jackson-core</artifactId>  <version>2.8.6</version></dependency><dependency>  <groupId>com.fasterxml.jackson.core</groupId>  <artifactId>jackson-databind</artifactId>  <version>2.7.0</version></dependency><dependency>  <groupId>com.fasterxml.jackson.core</groupId>  <artifactId>jackson-annotations</artifactId>  <version>2.8.6</version></dependency>

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<String, Integer> scoreByName = mapper.readValue(jsonSource, Map.class);List<String> names = mapper.readValue(jsonSource, List.class);//有自定义类Map<String, ResultValue> results = mapper.readValue(jsonSource, new TypeReference<Map<String, ResultValue>>() { } );

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。

0 0