#Jackson
推荐阅读:
前言:相比于 FastJson 和 Gson,Jackson 在性能、运行速度、开源社区的活跃度等方面的综合性能都要更好
一、简介
1、版本介绍
- Jackson 的 1.x 版本的包名是
org.codehaus.jackson
- 当升级到 2.x 版本时,包名变为
com.fasterxml.jackson
源码地址:FasterXML/jackson
2、核心模块
Jackson 的核心模块由三部分组成:
jackson-core
:核心包,提供基于"流模式"解析的相关 API,包括 JsonPaser 和 JsonGeneratorJackson 内部实现通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json
jackson-annotations
:注解包,提供标准注解功能jackson-databind
:数据绑定包, 提供基于"对象绑定" 解析的相关 APIObjectMapper
和"树模型" 解析的相关 APIJsonNode
基于"对象绑定" 解析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API
3、Maven 依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.2</version>
</dependency>
注:jackson-databind 依赖 jackson-core 和 jackson-annotations
完整 Maven 依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.11.2</version>
</dependency>
二、ObjectMapper
Jackson 最常用的 API 就是基于"对象绑定" 的 ObjectMapper:
-
ObjectMapper 可以从字符串、流、文件中解析 JSON,并创建表示已解析的 JSON 的 Java 对象
将 JSON 解析为 Java 对象也称为从 JSON 反序列化 Java 对象
-
ObjectMapper 也可以从 Java 对象创建 JSON
从 Java 对象生成 JSON 也称为将 Java 对象序列化为 JSON
-
Object 映射器可以将 JSON 解析为自定义的类对象,也可以解析置JSON树模型的对象
之所以称为ObjectMapper是因为它将JSON映射到Java对象(反序列化),或者将Java对象映射到JSON(序列化)
1、JSON 字符串转 Java 对象
ObjectMapper objectMapper = new ObjectMapper();
//1. JSON 字符串 --> Java 对象
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
Car car = objectMapper.readValue(carJson, Car.class);
//2. JSON 数组字符串 --> Java 对象数组
String carJsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
Car[] cars2 = objectMapper.readValue(carJsonArray, Car[].class);
//3. JSON 数组字符串 --> List
String carJsonList = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
List<Car> cars3 = objectMapper.readValue(carJsonList, new TypeReference<List<Car>>() {});
//4. JSON 字符串 --> Map
String carJsonMap = "{\"brand\":\"ford\", \"doors\":5}";
Map<String, Object> jsonMap = objectMapper.readValue(carJsonMap, new TypeReference<Map<String, Object>>() {});
2、Java 对象转 JSON 字符串
writeValue()
writeValueAsString()
- writeValueAsBytes()`
ObjectMapper objectMapper = new ObjectMapper();
Car car = new Car();
car.setBrand("BMW");
car.setDoors(4);
//1. Java 对象转 JSON,并写入 FileOutputStream
objectMapper.writeValue(new FileOutputStream("data/output-2.json"), car);
//2. Java 对象转 JSON 字符串
String json = objectMapper.writeValueAsString(car);
3、Jackson 日期转化
ObjectMapper objectMapper = new ObjectMapper();
//1. Date --> long(unix字符串)
String output = objectMapper.writeValueAsString(new Date());
//2. Date --> String
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
objectMapper.setDateFormat(dateFormat);
String output2 = objectMapper.writeValueAsString(new Date());
4、Jackson JSON 树模型
- Jackson 具有内置的树模型,可用于表示 JSON 对象
- 若不知道接收到的 JSON 格式,或者由于某种原因而不能创建一个类来表示,则可以用 Jackson 树模型
- 若需要在使用或转化 JSON 之前对其进行操作,也可以使用 Jackson 树模型
Jackson 树模型由 JsonNode 类表示,可以使用 Jackson ObjectMapper 将 JSON 解析为 JsonNode 树模型,就像使用自定义类一样
ObjectMapper objectMapper = new ObjectMapper();
String carJsonMulti = "{ \"brand\" : \"Mercedes\", " +
"\"doors\" : 5," +
" \"owners\" : [\"John\", \"Jack\", \"Jill\"]," +
" \"nestedObject\" : { \"field\" : \"value\" } }";
//1. 解析为 JsonNode 对象
JsonNode jsonNode = objectMapper.readValue(carJsonMulti, JsonNode.class); //法一
JsonNode jsonNode2 = objectMapper.readTree(carJsonMulti); //法二
//2. 浏览 JsonNode 树模型
JsonNode brandNode = jsonNode.get("brand");
String brand = brandNode.asText();
JsonNode doorsNode = jsonNode.get("doors");
int doors = doorsNode.asInt();
JsonNode array = jsonNode.get("owners");
String john = array.get(0).asText();
JsonNode child = jsonNode.get("nestedObject");
String field = child.get("field").asText();
//3. Java对象 --> JsonNode
Car car = new Car("Cadillac", 4);
JsonNode carJsonNode = objectMapper.valueToTree(car);
//4. JsonNode --> Java对象
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
JsonNode carJsonNode2 = objectMapper.readTree(carJson);
Car car2 = objectMapper.treeToValue(carJsonNode2, Car.class);
5、配置信息
//在反序列化时忽略在 json 中存在但 Java 对象不存在的属性
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//在序列化时日期格式默认为 yyyy-MM-dd'T'HH:mm:ss.SSSZ
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false)
//在序列化时忽略值为 null 的属性
objectMapper.setSerializationInclusion(Include.NON_NULL);
//忽略值为默认值的属性
objectMapper.setDefaultPropertyInclusion(Include.NON_DEFAULT);
三、JsonNode
- Jackson 可以将 JSON 读取到 JsonNode 实例中,然后将 JsonNode 写入 JSON
- 由于 JsonNode 类不可变,因此不能直接构建 JsonNode 实例,但可以创建 JsonNode 子类 ObjectNode 实例
作为 JsonNode 的子类,可以在使用 JsonNode 的任何地方使用 ObjectNode
ObjectMapper objectMapper = new ObjectMapper();
//1. 获取 JsonNode 字段
String jsonValue = "{\"field1\" : \"value1\", \"field2\" : 999}";
JsonNode jsonNode = objectMapper.readTree(jsonValue);
JsonNode field1 = jsonNode.get("field1");
JsonNode field2 = jsonNode.get("field2");
//2. 在路径中获取 JsonNode 字段
String jsonValue2 = "{\"identification\" : {\"name\" : \"James\",\"ssn: \"ABC123552\"}}";
JsonNode jsonNode2 = objectMapper.readTree(jsonValue2);
JsonNode nameNode = jsonNode2.at("/identification/name");
//3. 转换 JsonNode 字段
//3.1 将 String 字段值转换为 double/int/long
String f2Str = jsonNode.get("f2").asText();
double f2Dbl = jsonNode.get("f2").asDouble();
int f2Int = jsonNode.get("f2").asInt();
long f2Lng = jsonNode.get("f2").asLong();
//3.2 使用默认值转换(若字段值为空,则提供默认值)
String jsonValue3 = "{ \"f1\":\"Hello\", \"f2\":null }";
JsonNode jsonNode3 = objectMapper.readTree(jsonValue3);
String f2Value = jsonNode3.get("f2").asText("Default");
//3.3 若 json 中没有该值,jsonNode.get 返回 null,若此时调用 asText 等方法,将 NullPointerException
String jsonValue4 = "{ \"f1\":\"Hello\" }";
JsonNode jsonNode4 = objectMapper.readTree(jsonValue4);
JsonNode f2FieldNode = jsonNode.get("f2");
//4. 操作 JsonNode 的子类 ObjectNode
//4.1 创建一个 ObjectNode
ObjectNode objectNode = objectMapper.createObjectNode();
//4.2 Set ObjectNode 字段
String jsonValue5 = "{ \"f1\":\"Hello\" }";
JsonNode jsonNode5 = objectMapper.readTree(jsonValue5);
objectNode.set("child1", jsonNode5);
//4.3 Put ObjectNode 字段
objectNode.put("field1", "value1");
objectNode.put("field2", 123);
objectNode.put("field3", 999.999);
//4.4 删除字段
objectNode.remove("field1");
//5. 循环 JsonNode 字段
Iterator<String> fieldNames = objectNode.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
JsonNode field = jsonNode.get(fieldName);
}
四、JsonParser
JsonParser 的运行层级低于 ObjectMapper,因此 JsonParser 比 ObjectMapper 更快,但使用也比较麻烦
//1. 创建一个 JsonParser
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createParser(carJson);
//2. 用 JsonParser 转化 JSON
while (!parser.isClosed()) {
JsonToken jsonToken = parser.nextToken();
System.out.println("jsonToken = " + jsonToken);
}
使用 JsonParser 的 nextToken() 获得一个 JsonToken,可以使用此 JsonToken 实例检查给定的令牌:
START_OBJECT、END_OBJECT、START_ARRAY、END_ARRAY、FIELD_NAME、VALUE_EMBEDDED_OBJECT、VALUE_FALSE、VALUE_TRUE、VALUE_NULL、VALUE_STRING、VALUE_NUMBER_INT、VALUE_NUMBER_FLOAT
五、JsonGenerator
JsonGenerator 用于从 Java 对象(或代码从中生成 JSON 的任何数据结构)生成 JSON
//1. 创建一个 JsonGenerator
JsonFactory factory = new JsonFactory();
//1.1 第一个参数是生成的 JSON 的目标
JsonGenerator generator = factory.createGenerator(new File("data/output.json"), JsonEncoding.UTF8);
//2. 使用JsonGenerator生成JSON
generator.writeStartObject();
generator.writeStringField("brand", "Mercedes");
generator.writeNumberField("doors", 5);
generator.writeEndObject();
//3. 关闭 JsonGenerator
generator.close();
六、Jackson注解
Jackson 注解可以用来设置将 JSON 读入对象的方式或从对象生成什么 JSON 的方式
常用注解:
注解 | 用法 |
---|---|
@JsonProperty | 用于属性,把属性的名称序列化时转换为另外一个名称 |
@JsonFormat | 用于属性或者方法,把属性或方法的格式序列化时转换成指定的格式 |
@JsonPropertyOrder | 用于类, 指定属性在序列化时 json 中的顺序 |
@JsonCreator | 用于构造方法,和 @JsonProperty 配合使用,适用有参数的构造方法 |
@JsonAnySetter | 用于属性或者方法,设置未反序列化的属性名和值作为键值存储到 map 中 |
@JsonAnyGetter | 用于方法 ,获取所有未序列化的属性 |
1、Read + Write 注解
读+写注解:会影响从 JSON 读取 Java 对象以及将 Java 对象写入 JSON
@JsonIgnore
:将 JSON 读取到 Java 对象或将 Java 对象写入 JSON 时,都忽略该属性public class PersonIgnore { @JsonIgnore public long personId = 0; }
@JsonIgnoreProperties
:用于类,指定要忽略的类的属性列表@JsonIgnoreProperties({"firstName", "lastName"}) public class PersonIgnoreProperties { }
@JsonIgnoreType
:将整个类型(类)标记为在使用该类型的任何地方都将被忽略public class PersonIgnoreType { @JsonIgnoreType public static class Address { public String streetName = null; public String houseNumber = null; public String zipCode = null; public String city = null; public String country = null; } public long personId = 0; }
@JsonAutoDetect
:作用在类上,开启/禁止自动检测fieldVisibility
:字段的可见级别ANY
:任何级别的字段都可以自动识别NONE
:所有字段都不可以自动识别NON_PRIVATE
:非private修饰的字段可以自动识别PROTECTED_AND_PUBLIC
:被protected和public修饰的字段可以被自动识别PUBLIC_ONLY
:只有被public修饰的字段才可以被自动识别DEFAULT
:同PUBLIC_ONLY
2、Read 注解
读注解:仅影响将JSON 解析为对象的方式,即对JSON的读取
@JsonSetter
:当将 JSON 读入对象时,应将此 setter 方法的名称与 JSON 数据中的属性名称匹配若 Java 类内部使用的属性名称与 JSON 文件中使用的属性名称不同,这个注解就很有用
@JsonAnySetter
:为 JSON 对象中所有无法识别的字段调用相同的 setter 方法“无法识别”:指尚未映射到 Java 对象中的属性或设置方法的所有字段
@JsonCreator
:该 Java 对象具有一个构造函数,该构造函数可以将 JSON 对象的字段与Java对象的字段进行匹配@JacksonInject
:用于将值注入到解析的对象中,而不是从 JSON 中读取这些值public class PersonInject { public long id = 0; public String name = null; @JacksonInject public String source = null; }
将值注入 Java 对象:
InjectableValues inject = new InjectableValues.Std().addValue(String.class, "jenkov.com"); PersonInject personInject = new ObjectMapper().reader(inject) .forType(PersonInject.class) .readValue(new File("data/person.json"));
@JsonDeserialize
:为 Java 对象中给定的属性指定自定义反序列化器类
3、Write 注解
Write 注解:可以影响 Jackson 将 Java 对象序列化(写入)到 JSON 的方式
@JsonInclude
:仅在某些情况下包括属性例如:仅当属性为非null,非空或具有非默认值时,才应包括该属性
@JsonInclude(JsonInclude.Include.NON_EMPTY) public class PersonInclude { public long personId = 0; public String name = null; }
@JsonGetter
:通过调用 getter 方法而不是通过直接字段访问来获取某个字段值@JsonAnyGetter
:可以将 Map 用作要序列化为 JSON 的属性的容器@JsonPropertyOrder
:用于指定将 Java 对象的字段序列化为 JSON 的顺序@JsonPropertyOrder({"name", "personId"}) public class PersonPropertyOrder { public long personId = 0; public String name = null; }
@JsonRawValue
:表示该属性值应直接写入 JSON输 出@JsonValue
:不应该尝试序列化对象本身,而应在对象上调用将对象序列化为JSON字符串的方法@JsonSerialize
:用于为 Java 对象中的字段指定自定义序列化程序
# fastJson
1、json 字符串转 JSONObject
- 用
JSON.parseObject()
方法将 Json 字符串转化为 JSON 对象 - 用
JSONObject.get()
方法来获取 JSONObject 中的相对应的键对应的值
public void JsonStrToJSONObject(){
String JSON_OBJ_STR = "{\"studentName\":\"lily\",\"studentAge\":12}";
JSONObject jsonObject = JSON.parseObject(JSON_OBJ_STR);
System.out.println("StudentName: " + jsonObject.getString("studentName") + "," + "StudentAge: " + jsonObject.getInteger("studentAge"));
}
2、JSONObject 转 json字符串
public void JSONObjectToJSONString(){
//json字符串-简单对象型,加\转义
String JSON_OBJ_STR = "{\"studentName\":\"lily\",\"studentAge\":12}";
JSONObject jsonObject = JSON.parseObject(JSON_OBJ_STR);
String s = JSON.toJSONString(jsonObject);
System.out.println(s);
}
3、JSON字符串数组转 JSONArray
- 方式一:通过
jsonArray.size()
获取 JSONArray 元素个数,再通过getJSONObject(index)
获取相应位置的 JSONObject,循环变量取得 JSONArray 中的 JSONObject,再利用JSONObject.get()
进行取值 - 方式二:通过
jsonArray.iterator()
获取迭代器
public void JSONArrayToJSONStr(){
//json字符串-数组类型
String JSON_ARRAY_STR = "[{\"studentName\":\"lily\",\"studentAge\":12},{\"studentName\":\"lucy\",\"studentAge\":15}]";
JSONArray jsonArray = JSON.parseArray(JSON_ARRAY_STR);
//方式一
int size = jsonArray.size();
for(int i = 0;i < size;i++){
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
System.out.println("studentName: " + jsonObject1.getString("studentName") + ",StudentAge: " + jsonObject1.getInteger("studentAge"));
}
//方式二
Iterator<Object> iterator = jsonArray.iterator();
while (iterator.hasNext()){
JSONObject jsonObject2 = (JSONObject) iterator.next();
System.out.println("studentName: " + jsonObject2.getString("studentName") + ",StudentAge: " + jsonObject2.getInteger("studentAge"));
}
}
4、JSONArray 转 json 字符串
public void JSONArrayToJSONString(){
//json字符串-数组类型
String JSON_ARRAY_STR = "[{\"studentName\":\"lily\",\"studentAge\":12},{\"studentName\":\"lucy\",\"studentAge\":15}]";
JSONArray jsonArray = JSON.parseArray(JSON_ARRAY_STR);
String s = JSON.toJSONString(jsonArray);
System.out.println(s);
}
5、复杂JSON格式字符串转 JSONObject
public void JSONStringTOJSONObject(){
//复杂格式json字符串
private static final String COMPLEX_JSON_STR = "{\"teacherName\":\"crystall\"," +
"\"teacherAge\":27,\"course\":{\"courseName\":\"english\",\"code\":1270},\"students\":[{\"studentName\":\"lily\",\"studentAge\":12},{\"studentName\":\"lucy\",\"studentAge\":15}]}";
JSONObject jsonObject = JSON.parseObject(COMPLEX_JSON_STR);
// 获取简单对象
String teacherName = jsonObject.getString("teacherName");
Integer teacherAge = jsonObject.getInteger("teacherAge");
System.out.println("teacherName: " + teacherName + ",teacherAge " + teacherAge);
// 获取JSONObject对象
JSONObject course = jsonObject.getJSONObject("course");
// 获取JSONObject中的数据
String courseName = course.getString("courseName");
Integer code = course.getInteger("code");
System.out.println("courseName: " + courseName + " code: " + code);
// 获取JSONArray对象
JSONArray students = jsonObject.getJSONArray("students");
// 获取JSONArray的中的数据
Iterator<Object> iterator = students.iterator();
while (iterator.hasNext()){
JSONObject jsonObject1 = (JSONObject) iterator.next();
System.out.println("studentName: " + jsonObject1.getString("studentName") + ",StudentAge: "
+ jsonObject1.getInteger("studentAge"));
}
}
6、复杂JSONObject 转 json字符串
public void JSONObjectTOJSON(){
//复杂格式json字符串
private static final String COMPLEX_JSON_STR = "{\"teacherName\":\"crystall\"," +
"\"teacherAge\":27,\"course\":{\"courseName\":\"english\",\"code\":1270},\"students\":[{\"studentName\":\"lily\",\"studentAge\":12},{\"studentName\":\"lucy\",\"studentAge\":15}]}";
JSONObject jsonObject = JSON.parseObject(COMPLEX_JSON_STR);
String s = JSON.toJSONString(jsonObject);
System.out.println(s);
}
7、json字符串转 JavaBean
public class Student {
private String studentName;
private int studentAge;
}
public class Teacher {
private String teacherName;
private int teacherAge;
private Course course;
private List<Student> students;
}
public class Course {
private String courseName;
private int code;
}
转换:
public void JSONStringToJavaBeanObj(){
String JSON_OBJ_STR = "{\"studentName\":\"lily\",\"studentAge\":12}";
// 第一种方式
JSONObject jsonObject = JSON.parseObject(JSON_OBJ_STR);
String studentName = jsonObject.getString("studentName");
Integer studentAge = jsonObject.getInteger("studentAge");
Student student = new Student(studentName, studentAge);
// 第二种方式:使用TypeReference<T>类,由于其构造方法使用protected进行修饰,故创建其子类
Student student1 = JSON.parseObject(JSON_OBJ_STR, new TypeReference<Student>() {});
// 第三种方式:通过反射(推荐)
Student student2 = JSON.parseObject(JSON_OBJ_STR, Student.class);
}
8、JavaBean 转 json 字符串
public void JavaBeanToJsonString(){
Student lily = new Student("lily", 12);
String s = JSON.toJSONString(lily);
System.out.println(s);
}
9、json 字符串数组转 JavaBean-List
public void JSONStrToJavaBeanList(){
// 方式一:
JSONArray jsonArray = JSON.parseArray(JSON_ARRAY_STR);
//遍历JSONArray
List<Student> students = new ArrayList<Student>();
Iterator<Object> iterator = jsonArray.iterator();
while (iterator.hasNext()){
JSONObject next = (JSONObject) iterator.next();
String studentName = next.getString("studentName");
Integer studentAge = next.getInteger("studentAge");
Student student = new Student(studentName, studentAge);
students.add(student);
}
// 方式二,使用TypeReference<T>类,由于其构造方法使用protected进行修饰,故创建其子类
List<Student> studentList = JSON.parseObject(JSON_ARRAY_STR,new TypeReference<ArrayList<Student>>() {});
// 方式三,使用反射
List<Student> students1 = JSON.parseArray(JSON_ARRAY_STR, Student.class);
System.out.println(students1);
}
10、JavaBean-List 转 json 字符串数组
public void JavaBeanListToJSONStr(){
Student student = new Student("lily", 12);
Student student1 = new Student("lucy", 13);
List<Student> students = new ArrayList<Student>();
students.add(student);
students.add(student1);
String s = JSON.toJSONString(student);
System.out.println(s);
}
11、复杂嵌套json格式字符串转 JavaBean_obj
public void ComplexJsonStrToJavaBean(){
//第一种方式,使用TypeReference<T>类,由于其构造方法使用protected进行修饰,故创建其子类
Teacher teacher = JSON.parseObject(COMPLEX_JSON_STR, new TypeReference<Teacher>() {});
// 第二种方式,使用反射
Teacher teacher1 = JSON.parseObject(COMPLEX_JSON_STR, Teacher.class);
}
12、JavaBean_obj 转复杂 json 格式字符串
public void JavaBeanToComplexJSONStr(){
Teacher teacher = JSON.parseObject(COMPLEX_JSON_STR, Teacher.class);
String s = JSON.toJSONString(teacher);
System.out.println(s);
}