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依赖:
    目前jackson的最新版本已经将套件组合到jackson-databind中,引入jackson-databind将自动引入另外两个依赖。(可见https://www.baeldung.com/jackson-object-mapper-tutorial)
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值