Java(或JVM平台)的标准JSON库,或者被称为“ Java的最佳JSON解析器”。html
Jackson提供了一套用于Java(和JVM平台)的数据处理工具,包括旗舰级流JSON解析器/生成器库,匹配的数据绑定库(与JSON之间的POJO)和附加的数据格式模块。以Avro, BSON, CBOR, CSV, Smile, (Java)Properties, Protobuf, XML 或YAML编码的处理数据 ; 甚至还有大量的数据格式模块,以支持普遍使用的数据类型的数据类型,例如 Guava, Joda, PCollections 等等。java
实际的核心组件位于他们本身的项目下-包括两个核心软件包: jackson-core、 jackson-databind。git
jackson-core项目包含Jackson数据处理器使用的抽象核心流式解析器和生成器,还包括处理JSON格式的解析器、生成器的默认实现。jackson-databind包含用于Jackson数据处理器的通用数据绑定功能和树模型。它基于StreamingAPI(流解析器、生成器)包构建,并使用Jackson注释进行配置。github
流式API是一套比较底层的API,速度快,可是使用起来特别麻烦。它主要是有两个核心类,一个是JsonGenerator,用来生成json,另外一个是JsonParser,用来读取json内容。
使用一般从建立可重用(而且在配置后是线程安全的)JsonFactory实例开始:spring
JsonFactory factory = new JsonFactory();
// 配置(若有必要):
factory.enable(JsonParser.Feature.ALLOW_COMMENTS);
// 另外,您也能够方便地ObjectMapper(从Jackson-Databind软件包中得到)。若是是这样,您能够执行如下操做:
JsonFactory factory = objectMapper.getFactory();
复制代码
官方使用示例:Reading and Writing Event Streamsjson
JsonFactory f = mapper.getFactory();
// 也能够直接构造 JsonFactory factory = new JsonFactory();
// 首先写入
File jsonFile = new File("test.json");
JsonGenerator g = f.createGenerator(jsonFile);
// 写入 JSON: { "message" : "Hello world!" }
g.writeStartObject();
g.writeStringField("message", "Hello world!");
g.writeEndObject();
g.close();
// 而后读取
JsonParser p = f.createParser(jsonFile);
JsonToken t = p.nextToken();
t = p.nextToken();
if ((t != JsonToken.FIELD_NAME) || !"message".equals(p.getCurrentName())) {
// handle error
}
t = p.nextToken();
if (t != JsonToken.VALUE_STRING) {
// similarly
}
String msg = p.getText();
System.out.printf("My message to you is: %s!\n", msg);
p.close();
复制代码
jackson-databind软件包依赖于jackson-core和jackson-annotations软件包,可是当使用Maven或Gradle之类的构建工具时,依赖项会自动包括在内。基本使用:后端
//建立一个com.fasterxml.jackson.databind.ObjectMapper用于全部数据绑定的实例,ObjectMapper是线程安全的,应该尽可能的重用。
ObjectMapper mapper = new ObjectMapper();
// 字符串反序列化为对象
Grade grade = mapper.readValue(jsonStr, Grade.class);
// Jackson是基于JavaBean来序列化属性的,属性要有GETTER方法,才会输出该属性
Map<String, ResultValue> results = mapper.readValue(jsonSource, new TypeReference<Map<String, ResultValue>>() { } );
// 对象序列号化为json字符串
String gradeStr = mapper.writeValueAsString(grade);
// 对象序列号化为byte数组
byte[] jsonBytes = mapper.writeValueAsBytes(grade);
// 写入文件
mapper.writeValue(new File("result.json"), grade);
复制代码
在调用了某个api后,须要解析返回的json数据获取信息,这种状况下为json建立一个对应的类是很不方便的。此时使用Tree Model来解析json就比较方便了api
JsonNode root = mapper.readTree(rerenjson);
JsonNode user = root.get("user");
root.with("other").put("type", "student");
int id = user.get("id").asInt();
String name = user.get("name").asText();
JsonNode avators = user.get("avatar");
if (avators.isArray()) {
for (Iterator it = avators.getElements(); it.hasNext(); ){
JsonNode avator = it.next();
if ("tiny".equals(avator.get("type").asText())) {
String ava = avator.get("url").asText();
break;
}
}
}
复制代码
Jackson的一项有用(但不是很广为人知)的功能是它可以进行任意的POJO到POJO转换。通常作法,首先将POJO编写为JSON,其次将JSON绑定到另外一种POJO中。Jackson实现跳过JSON的实际生成,并使用更高效的中间实现。数组
// 基本使用
ResultType result = mapper.convertValue(sourceObject, ResultType.class);
// List<Integer> 转 int[]
List<Integer> sourceList = ...;
int[] ints = mapper.convertValue(sourceList, int[].class);
// POJO 转 Map!
Map<String,Object> propertyMap = mapper.convertValue(pojoValue, Map.class);
// POJO 转 back
PojoType pojo = mapper.convertValue(propertyMap, PojoType.class);
// 解码Base64!(缺省字节[]表示是base64编码字串)
String base64 = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz";
byte[] binary = mapper.convertValue(base64, byte[].class);
复制代码
一、经常使用注解:
@JsonIgnore 此注解用于属性上,做用是进行JSON操做时忽略该属性。
@JsonFormat 此注解用于属性上,做用是把Date类型直接转化为想要的格式,如@JsonFormat(pattern = “yyyy-MM-dd HH-mm-ss”)。
@JsonProperty 此注解用于属性上,做用是把该属性的名称序列化为另一个名称,如把trueName属性序列化为name,@JsonProperty(“name”)。也能够直接在类上添加注解 @JsonIgnoreProperties({ "a", "b" }),跳过a、b属性。
@JsonCreator构造函数能够是公共的,也能够是私有的。Jackson不须要定义“默认构造函数”(不带参数的构造函数)。安全
二、Mapper的一些实用配置:(其余配置可见上述jackson-databind官方连接)
// (空对象是否抛出异常)
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// (日期改成时间戳)
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// (特殊字符和打印符,这在FastJson曾是个bug)
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// (单引号)
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
复制代码
SpringMVC内置json解析器就是Jackson,以SpringBoot技术栈开发的话,用默认的Jackson是最好的。
spring:
jackson:
# 设置属性命名策略,对应jackson下PropertyNamingStrategy中的常量值,SNAKE_CASE-返回的json驼峰式转下划线,json body下划线传到后端自动转驼峰式
property-naming-strategy: SNAKE_CASE
# 全局设置@JsonFormat的格式pattern
date-format: yyyy-MM-dd HH:mm:ss
# 当地时区
locale: zh
# 设置全局时区
time-zone: GMT+8
# 经常使用,全局设置pojo或被@JsonInclude注解的属性的序列化方式
default-property-inclusion: NON_NULL #不为空的属性才会序列化,具体属性可看JsonInclude.Include
# 常规默认,枚举类SerializationFeature中的枚举属性为key,值为boolean设置jackson序列化特性,具体key请看SerializationFeature源码
serialization:
WRITE_DATES_AS_TIMESTAMPS: true # 返回的java.util.date转换成timestamp
FAIL_ON_EMPTY_BEANS: true # 对象为空时是否报错,默认true
# 枚举类DeserializationFeature中的枚举属性为key,值为boolean设置jackson反序列化特性,具体key请看DeserializationFeature源码
deserialization:
# 经常使用,json中含pojo不存在属性时是否失败报错,默认true
FAIL_ON_UNKNOWN_PROPERTIES: false
# 枚举类MapperFeature中的枚举属性为key,值为boolean设置jackson ObjectMapper特性
# ObjectMapper在jackson中负责json的读写、json与pojo的互转、json tree的互转,具体特性请看MapperFeature,常规默认便可
mapper:
# 使用getter取代setter探测属性,如类中含getName()但不包含name属性与setName(),传输的vo json格式模板中依旧含name属性
USE_GETTERS_AS_SETTERS: true #默认false
# 枚举类JsonParser.Feature枚举类中的枚举属性为key,值为boolean设置jackson JsonParser特性
# JsonParser在jackson中负责json内容的读取,具体特性请看JsonParser.Feature,通常无需设置默认便可
parser:
ALLOW_SINGLE_QUOTES: true # 是否容许出现单引号,默认false
# 枚举类JsonGenerator.Feature枚举类中的枚举属性为key,值为boolean设置jackson JsonGenerator特性,通常无需设置默认便可
# JsonGenerator在jackson中负责编写json内容,具体特性请看JsonGenerator.Feature
复制代码
默认配置(配置文件配置JacksonAutoConfiguration)和用户自定义Java代码配置只须要一种便可。
jackson
jackson-core
jackson-databind 平时咱们使用最多的就是数据绑定吧,配置好以后真让人省心,树模型和类型转换也能为咱们的工做带来便利,流式API平常使用不是太方便。但愿这篇文章能对大家有帮助。欢迎你们一块儿学习,有误之处烦请你们指正。