jackson入门用法

3,687 阅读3分钟

依赖引入

如果项目中引入了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相关方法都是线程安全的,因此使用的时候可以引入单例模式