上一篇博文我们使用json-lib 来对json字符串和java对象进行互转
https://blog.csdn.net/liuying1802028915/article/details/92068465
这篇博文我们来使用jackson来对json字符串和java 对象进行互转
这里引用一下网上对jackson的介绍
https://www.dubby.cn/detail.html?id=9068
Jackson作为一个知名,并且经典的Java平台的JSON库,有人说它是最好的JSON解析工具,或者只是一个简单的还行的JSON解析库,不管如何Jackson都是一个值得一学,值得一用的JSON处理库。
Jackson不仅支持流式处理json,还支持数据绑定(POJO和JSON之间的相互转化),甚至还拓展了很多其他第三方库所支持的数据格式(如:Avro, BSON, CBOR, CSV, Smile, (Java) Properties, Protobuf, XML和YAML,Guava, Joda, PCollections)。
Jackson的三个核心模块:
jackson-core
:定义了低级的流式API,包括了JSON处理细节。jackson-annotations
:包含了Jackson的注解。jackson-databind
:实现了对象和JSON之间的转换,这个包依赖上面两个包。以上是摘抄来的 ,出自https://www.dubby.cn/detail.html?id=9068
前段时间在工作中我遇到了一个这样的问题,就是老大让我对我们项目中 jacason-databind.2.8.11.jar 2.8.11以下版本进行升级,升级到2.8.11,但是升级完之后,导致产品图表数据出不来,进过排查发现是后端转换的json数据跟之前的有差别,之前是用的是比2.8.11低的版本jar包,现在升级到2.8.11之后,该jar包对安全性做了提高,但是改了其中的一些内容,具体内容还没搞清楚,当时这个问题是老大解决的,所以这次就对jackson做个练习。
因为最近在研究json字符串和java对象的互转,这次就使用jackson 来进行 json的序列化和反序列化
一.首先新建一个maven项目,这里不再赘述
二。在项目的pom文件中假如对jackson-databind的依赖
com.fasterxml.jackson.core
jackson-databind
2.5.3
之后导入依赖包之后发现
jackson-databind 其实依赖了 jackson-core 和 jackson-annotation 这两个jar包,这也就证明了我在工作中为了升级jackson-databind包是相应的也将 jackson-core 和 jackson-annotation 相应升级
三。接下来我们来写代码
1.首先我们新建 com.taoj.entity.User 类
package com.taoj.entity;
import java.util.Date;
public class User {
private String name;
private Integer age;
private Date birthday;
private String email;
public User(String name, Integer age, Date birthday, String email) {
this.name = name;
this.age = age;
this.birthday = birthday;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
", email='" + email + '\'' +
'}';
}
}
这里写了一个User 实体类,包括有参构造函数,get set 方法 toString方法
下面写一个测试类
1》
将 java对象 转换成 json 字符串
/**
* 将 java对象 转换成 json 字符串
*/
public static void conventObjectToJson(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = sdf.parse("1981-02-19");
} catch (ParseException e) {
e.printStackTrace();
}
User user = new User("梁朝伟", 25, date, "[email protected]");
//新建ObjectMapper对象
ObjectMapper objectMapper = new ObjectMapper();
//使用ObjectMapper对象对 User对象进行转换
String json = null;
try {
json = objectMapper.writeValueAsString(user);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(json);
}
输出为:
{"name":"梁朝伟","age":25,"birthday":351360000000,"email":"[email protected]"}
2》
将 List 转换成 json 字符串
/**
* 将 List 转换成 json 字符串
*/
public static void conventListToJson(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = null;
Date date2 = null;
try {
date1 = sdf.parse("1987-10-01");
date2 = sdf.parse("1989-06-06");
} catch (ParseException e) {
e.printStackTrace();
}
User user1 = new User("周润发", 23, date1, "[email protected]");
User user2 = new User("刘德华", 25, date2, "[email protected]");
List list = new ArrayList();
list.add(user1);
list.add(user2);
ObjectMapper objectMapper = new ObjectMapper();
String listStr = null;
try {
listStr = objectMapper.writeValueAsString(list);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(listStr);
}
输出为:[{"name":"周润发","age":23,"birthday":560016000000,"email":"[email protected]"},{"name":"刘德华","age":25,"birthday":613062000000,"email":"[email protected]"}]
3》
将 json字符串 转换为 java对象
/**
* 将 json字符串 转换为 java对象
*/
public static void conventJsonToObject(){
String json = "{\"name\":\"周润发\",\"age\":23,\"birthday\":560016000000,\"email\":\"[email protected]\"}";
ObjectMapper objectMapper = new ObjectMapper();
User user = null;
try {
user = objectMapper.readValue(json, User.class);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(user);
}
当运行这个方法时 发现报错了
错误如下:
null
com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.taoj.entity.User]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
他说没有默认的构造函数,的确User对象,我只添加了有参构造函数,默认的无参构造函数就没了,现在给User对象添加无参构造函数
添加后的User.java 如下
package com.taoj.entity;
import java.util.Date;
public class User {
private String name;
private Integer age;
private Date birthday;
private String email;
public User() {
}
public User(String name, Integer age, Date birthday, String email) {
this.name = name;
this.age = age;
this.birthday = birthday;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
", email='" + email + '\'' +
'}';
}
}
此时运行刚刚那个方式时输出为:
User{name='周润发', age=23, birthday=Thu Oct 01 00:00:00 CST 1987, email='[email protected]'}
4》
将json 字符串 转换为 java对象
/**
* 将json 字符串 转换为 java对象
*/
public static void conventJsonToList(){
String json = "[{\"name\":\"周润发\",\"age\":23,\"birthday\":560016000000,\"email\":\"[email protected]\"},{\"name\":\"刘德华\",\"age\":25,\"birthday\":613062000000,\"email\":\"[email protected]\"}]";
ObjectMapper objectMapper = new ObjectMapper();
List list = null;
try {
list = objectMapper.readValue(json, new TypeReference>(){});
} catch (IOException e) {
e.printStackTrace();
}
for(User user : list){
System.out.println(user);
}
}
以上是如何使用ObjectMapper对象实现对json字符串和java互转的四个方法,这里仅仅是一个练习。记录一下,防止以后忘记。
当然关于jackson-databind的学习还得继续,最好是通读一下源码这样才能真正的了解jackson的核心,加油
不积跬步,无以至千里
不积小流,无以成江海
这里引入一下 https://blog.csdn.net/u011054333/article/details/80504154 博文中的一个内容 ,就是
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE); 和
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);的用法
public static void conventObjectToJsonWithNull(){
User user = new User("黎明", 0, null, "上海");
ObjectMapper objectMapper = new ObjectMapper();
// objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
// objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
try {
//将对象转换成字符串
String json = objectMapper.writeValueAsString(user);
System.out.println(json);
//将字符串转换成对象
User user2 = objectMapper.readValue(json, User.class);
System.out.println(user2);
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
如上方法 把
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE); 和
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 注释掉了
输出结果为:
{"name":"黎明","age":0,"birthday":null,"email":"上海"}
User{name='黎明', age=0, birthday=null, email='上海'}
第一行为json ,故可以转换成相应的java对象
换一种方法
public static void conventObjectToJsonWithNull(){
User user = new User("黎明", 0, null, "上海");
ObjectMapper objectMapper = new ObjectMapper();
// objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
try {
//将对象转换成字符串
String json = objectMapper.writeValueAsString(user);
System.out.println(json);
//将字符串转换成对象
User user2 = objectMapper.readValue(json, User.class);
System.out.println(user2);
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
如上 只把
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);注释掉了
输出结果为:
{"name":"黎明","age":0,"birthday":null,"email":"上海"}
User{name='黎明', age=0, birthday=null, email='上海'}
看来是没有影响
在看下面
public static void conventObjectToJsonWithNull(){
User user = new User("黎明", 0, null, "上海");
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
try {
//将对象转换成字符串
String json = objectMapper.writeValueAsString(user);
System.out.println(json);
//将字符串转换成对象
User user2 = objectMapper.readValue(json, User.class);
System.out.println(user2);
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
两句都放开 输出结果为:
{"User":{"name":"黎明","age":0,"birthday":null,"email":"上海"}}
User{name='null', age=null, birthday=null, email='null'}
没有将字符串转换成相应的对象 对象的值为空了
下面
public static void conventObjectToJsonWithNull(){
User user = new User("黎明", 0, null, "上海");
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
// objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
try {
//将对象转换成字符串
String json = objectMapper.writeValueAsString(user);
System.out.println(json);
//将字符串转换成对象
User user2 = objectMapper.readValue(json, User.class);
System.out.println(user2);
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
如上只放开
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
输出结果为:
输出报错了,这里简单认识了这两个属性,记录一下,详细的话可以看这篇
https://blog.csdn.net/u011054333/article/details/80504154