Java生态圈中有很多处理JSON和XML格式化的类库,Jackson是其中比较著名的一个。虽然JDK自带了XML处理类库,但是相对来说比较低级,使用本文介绍的Jackson等高级类库处理起来会方便很多。
引入类库
由于Jackson相关类库按照功能分为几个相对独立的,所以需要同时引入多个类库,为了方便我将版本号单独提取出来设置,相关Gradle配置如下。
ext {
jacksonVersion = '2.9.5'
}
dependencies {
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: jacksonVersion
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jacksonVersion
compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: jacksonVersion
// 引入XML功能
compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: jacksonVersion
// 比JDK自带XML实现更高效的类库
compile group: 'com.fasterxml.woodstox', name: 'woodstox-core', version: '5.1.0'
// Java 8 新功能
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: jacksonVersion
compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-parameter-names', version: jacksonVersion
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version: jacksonVersion
compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.16.22'
}
Maven配置请去mvnrepository搜索。
Jackson注解
Jackson类库包含了很多注解,可以让我们快速建立Java类与JSON之间的关系。详细文档可以参考Jackson-Annotations。下面介绍一下常用的。
属性命名
@JsonProperty
注解指定一个属性用于JSON映射,默认情况下映射的JSON属性与注解的属性名称相同,不过可以使用该注解的value
值修改JSON属性名,该注解还有一个index
属性指定生成JSON属性的顺序,如果有必要的话。
属性包含
还有一些注解可以管理在映射JSON的时候包含或排除某些属性,下面介绍一下常用的几个。
@JsonIgnore
注解用于排除某个属性,这样该属性就不会被Jackson序列化和反序列化。
@JsonIgnoreProperties
注解是类注解。在序列化为JSON的时候,@JsonIgnoreProperties({"prop1", "prop2"})
会忽略pro1和pro2两个属性。在从JSON反序列化为Java类的时候,@JsonIgnoreProperties(ignoreUnknown=true)
会忽略所有没有Getter和Setter的属性。该注解在Java类和JSON不完全匹配的时候很有用。
@JsonIgnoreType
也是类注解,会排除所有指定类型的属性。
序列化相关
@JsonPropertyOrder
和@JsonProperty
的index
属性类似,指定属性序列化时的顺序。
@JsonRootName
注解用于指定JSON根属性的名称。
处理JSON
简单映射
我们用Lombok设置一个简单的Java类。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Friend {
private String nickname;
private int age;
}
然后就可以处理JSON数据了。首先需要一个ObjectMapper对象,序列化和反序列化都需要它。
ObjectMapper mapper = new ObjectMapper();
Friend friend = new Friend("yitian", 25);
// 写为字符串
String text = mapper.writeValueAsString(friend);
// 写为文件
mapper.writeValue(new File("friend.json"), friend);
// 写为字节流
byte[] bytes = mapper.writeValueAsBytes(friend);
System.out.println(text);
// 从字符串中读取
Friend newFriend = mapper.readValue(text, Friend.class);
// 从字节流中读取
newFriend = mapper.readValue(bytes, Friend.class);
// 从文件中读取
newFriend = mapper.readValue(new File("friend.json"), Friend.class);
System.out.println(newFriend);
程序结果如下。可以看到生成的JSON属性和Java类中定义的一致。
{
"nickname":"yitian","age":25}
Friend(nickname=yitian, age=25)
集合的映射
除了使用Java类进行映射之外,我们还可以直接使用Map和List等Java集合组织JSON数据,在需要的时候可以使用readTree方法直接读取JSON中的某个属性值。需要注意的是从JSON转换为Map对象的时候,由于Java的类型擦除,所以类型需要我们手动用new TypeReference<T>
给出。
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = new HashMap<>();
map.put("age", 25);
map.put("name", "yitian");
map.put("interests",