依赖引入
如果项目中引入了spring-boot-web依赖,那么就不需要再引入jackson,因为spring-boot-web已经包含了。
如果是单独引入的话,则pom.xml填写如下配置
<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>
测试对象
package com.example.jackson;
public class Student {
private String name;
private Integer age;
private String profileImageUrl;
public String getName() {
return name;
}
public Student setName(String name) {
this.name = name;
return this;
}
public Integer getAge() {
return age;
}
public Student setAge(Integer age) {
this.age = age;
return this;
}
public String getProfileImageUrl() {
return profileImageUrl;
}
public Student setProfileImageUrl(String profileImageUrl) {
this.profileImageUrl = profileImageUrl;
return this;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", profileImageUrl='" + profileImageUrl + '\'' +
'}';
}
}
序列化和反序列化方法封装
使用jackson序列化和反序列化json,主要是靠ObjectMapper类来实现,因此可以使用一个全局的ObjectMapper,然后封装序列化和反序列化操作,代码如下:
package com.example.jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.util.StringUtils;
public class JsonUtil {
private static final ObjectMapper objectMapper = new ObjectMapper();
public static <T> String obj2String(T obj) {
if (obj == null) {
return null;
}
try {
return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static <T> T string2Obj(String str, Class<T> clazz) {
if (StringUtils.isEmpty(str) || clazz == null) {
return null;
}
try {
return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
从方法中可以看出,序列化对象用到ObjectMapper的writeValueAsString()方法,而反序列化json则用到ObjectMapper的readValue方法
测试代码
package com.example.jackson;
import org.junit.jupiter.api.Test;
class JsonUtilTest {
@Test
public void obj2String() {
Student student = new Student();
student.setAge(20);
student.setName("json");
student.setProfileImageUrl("www.baidu.com");
System.out.println(JsonUtil.obj2String(student));
}
@Test
void string2Obj() {
String json = "{\"studentName\":\"json\",\"studentAge\":20,\"profileImageUrl\":\"www.baidu.com\"}";
Student student = JsonUtil.string2Obj(json, Student.class);
System.out.println(student);
}
}
jackson的常用注解
@JsonProperty
该注解可以在json串和对象属性名形成映射,比如
@JsonProperty(value = "studentName")
private String name;
在name上添加该注解,值设置为studentName,那么json字符串中对应的键就只能是studentName
{"profileImageUrl":"www.baidu.com","studentName":"json","studentAge":20}
@JsonIgnore
使用该注解的字段,在json的序列化和反序列化中都会被忽略
@JsonFormat
日期的序列化格式,比如
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date birthdate;
@JsonIgnoreProperties(ignoreUnknown = true)
如果json字符串中的属性个数小于java对象中的属性个数,可以顺利转换,java中多的那个属性为null
如果json字符串中出现java对象中没有的属性,则在将json转换为java对象时会报错:Unrecognized field, not marked as ignorable
解决方法1:
在目标对象的类级别上添加注解:@JsonIgnoreProperties(ignoreUnknown = true)
解决方法2:
public class JsonUtil {
private static ObjectMapper objectMapper = new ObjectMapper();
static {
//忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
}
Tree Node解析JSON
通常都是直接编写对象类,然后将JSON直接解析为对象类。还有一种方法就是一个一个读取json串中的属性。下面进行演示:
{
"profileImageUrl" : "www.baidu.com",
"birthdate" : "2020-08-07 00:13:07",
"studentName" : "jhon",
"studentAge" : 20,
"father": {
"name": "mac"
}
}
@Test
void readTreeNode() throws Exception {
String json = "{\n" +
" \"profileImageUrl\" : \"www.baidu.com\",\n" +
" \"birthdate\" : \"2020-08-07 00:13:07\",\n" +
" \"studentName\" : \"jhon\",\n" +
" \"studentAge\" : 20,\n" +
" \"father\": {\n" +
" \"name\": \"mac\"\n" +
" }\n" +
"}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(json);
System.out.println(jsonNode.get("birthdate").asText());
System.out.println(jsonNode.get("studentAge").asText());
System.out.println(jsonNode.get("father").get("name").asText());
}
jackson入门使用非常简单,主要就是ObjectMapper类的方法调用。 需要注意,ObjectMapper的read和write相关方法都是线程安全的,因此使用的时候可以引入单例模式