Jackson 序列化库详解

发布于 2023-11-12 19:06:53 字数 7270 浏览 34 评论 0

Jackson 是一个功能强大的 Java 序列化库。除了支持常用的 json,同时还支持 Smile,BSON,XML,CSV,YAML。

Jackson 的 json 库提供了 3 种 API:

  • Streaming API : 性能最好
  • Tree Model : 最灵活
  • Data Binding : 最方便

其中最常用到的就是 Data Binding 了,基本的用法如下

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(foo);
Foo foo = mapper.readValue(json, Foo.class);

ObjectMapper 是线程安全的,应该尽量的重用

需要注意的是,Jackson 是基于 JavaBean 来序列化属性的,如果属性没有 GETTER 方法,默认是不会输出该属性的。但是在序列化的时候,经常会有特殊的需求来对输出的结果进行自定义。

比如不输出某几个属性,或者自定义属性的名字,等等。

一. 引入类库

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.7</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.7</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.7</version>
</dependency>

二. Data Binding

我们先创建两个实体封装类:

public class Student {
    private String name;
    private Integer age;
    private List<Subject> subjects;
}
public class Subject {
    private Integer score;
    private String subjectName;
    @JsonFormat(pattern = "yyyy/MM/dd hh:mm:ss", locale = "zh", timezone = "GMT+8")
    private Date time;//考试时间
                                        
    public Subject(Integer score, String subjectName, Date time) {
        this.score = score;
        this.subjectName = subjectName;
        this.time = time;
    }
}

2.1 生成 JSON 字符串

public void testDataBindingGenerate() throws JsonProcessingException {
    Student student = new Student();
    student.setName("张三");
    student.setAge(15);
    List<Subject> subjects = new ArrayList<>();
    student.setSubjects(subjects);
    subjects.add(new Subject(75, "数学", new Date()));
    subjects.add(new Subject(68, "语文", new Date()));
    subjects.add(new Subject(35, "英语", new Date()));
    ObjectMapper objectMapper = new ObjectMapper();
    String json = objectMapper.writeValueAsString(student);
    System.out.println(json);
}

2.2 解析 JSON 字符串

public void testDataBindingParseJson() throws IOException {
    String json = "{\"name\":\"张三\",\"age\":15,\"subjects\":[{\"score\":75,\"subjectName\":\"数学\"," +
            "\"time\":\"2020/05/03 02:38:14\"},{\"score\":68,\"subjectName\":\"语文\",\"time\":\"2020/05/03 02:38:14\"},{\"score\":35,\"subjectName\":\"英语\",\"time\":\"2020/05/03 02:38:14\"}]}";
    ObjectMapper objectMapper = new ObjectMapper();
    Student student = objectMapper.readValue(json, Student.class);
    System.out.println(student);
}

三. Tree Model

树模式在没有实体类封装时使用,它能将 JSON 字符串转换为 ObjectNode 的形式,其中 ObjectNode 可以嵌套其他的 ObjectNode ,也就是说复杂的 JSON 结构都能够轻松的转换为一个 ObjectNode 。而 ObjectNode 可以代表一个对象也可以代表一个数组。

3.1 生成 JSON 字符串

public void testJSONGenerate() throws IOException {
    JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance;
    //JsonFactory 实例,线程安全
    JsonFactory jsonFactory = new JsonFactory();
    //根节点
    ObjectNode rootNode = jsonNodeFactory.objectNode();
    //往根节点中添加普通键值对
    rootNode.put("name", "aaa");
    rootNode.put("email", "aaa@aa.com");
    rootNode.put("age", 24);
    //往根节点中添加一个子对象
    ObjectNode petsNode = jsonNodeFactory.objectNode();
    petsNode.put("petName", "kitty")
            .put("petAge", 3);
    rootNode.set("pets", petsNode);
    //往根节点中添加一个数组
    ArrayNode arrayNode = jsonNodeFactory.arrayNode();
    arrayNode.add("java")
            .add("linux")
            .add("mysql");
    rootNode.set("skills", arrayNode);
    //调用 ObjectMapper 的 writeTree 方法根据节点生成最终 json 字符串
    JsonGenerator generator = jsonFactory.createGenerator(System.out);
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.writeTree(generator, rootNode);
}

3.2 解析 JSON 字符串

public void testJsonParse() throws IOException {
    String str = "{\"name\":\"aaa\",\"email\":\"aaa@aa.com\",\"age\":24,\"pets\":{\"petName\":\"kitty\",\"petAge\":3},\"skills\":[\"java\",\"linux\",\"mysql\"]}";
    ObjectMapper objectMapper = new ObjectMapper();
    //使用 ObjectMapper 的 readValue 方法将 json 字符串解析到 JsonNode 实例中
    JsonNode rootNode = objectMapper.readTree(str);
    JsonNode pets = rootNode.get("pets");
    System.out.println(pets);
}

四. Streaming API

4.1 生成 JSON 字符串

 @Test
public void test() throws IOException {
    JsonFactory jfactory = new JsonFactory();

    /*** write to file ***/
    JsonGenerator jGenerator = jfactory.createGenerator(new File(
            "C:\\Users\\Lenovo\\Desktop\\Hello.json"),  JsonEncoding.UTF8);
    jGenerator.writeStartObject(); // {

    jGenerator.writeStringField("name", "mkyong"); // "name" : "mkyong"
    jGenerator.writeNumberField("age", 29); // "age" : 29

    jGenerator.writeFieldName("messages"); // "messages" :
    jGenerator.writeStartArray(); // [

    jGenerator.writeString("msg 1"); // "msg 1"
    jGenerator.writeString("msg 2"); // "msg 2"
    jGenerator.writeString("msg 3"); // "msg 3"

    jGenerator.writeEndArray(); // ]

    jGenerator.writeEndObject(); // }
    jGenerator.close();

}

4.2 解析 JSON 字符串

@Test
public void test2() throws IOException {
    JsonFactory jfactory = new JsonFactory();
    /*** read from file ***/
    JsonParser jParser = jfactory.createParser(new File("C:\\Users\\Lenovo\\Desktop\\Hello.json"));
    // loop until token equal to "}"
    while (jParser.nextToken() != JsonToken.END_OBJECT) {

        String fieldname = jParser.getCurrentName();
        if ("name".equals(fieldname)) {

            // current token is "name",
            // move to next, which is "name"'s value
            jParser.nextToken();
            System.out.println(jParser.getText()); // display mkyong

        }

        if ("age".equals(fieldname)) {

            // current token is "age",
            // move to next, which is "name"'s value
            jParser.nextToken();
            System.out.println(jParser.getIntValue()); // display 29

        }

        if ("messages".equals(fieldname)) {

            jParser.nextToken(); // current token is "[", move next

            // messages is array, loop until token equal to "]"
            while (jParser.nextToken() != JsonToken.END_ARRAY) {

                // display msg1, msg2, msg3
                System.out.println(jParser.getText());

            }

        }

    }
    jParser.close();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

罪歌

暂无简介

0 文章
0 评论
24 人气
更多

推荐作者

内心激荡

文章 0 评论 0

JSmiles

文章 0 评论 0

左秋

文章 0 评论 0

迪街小绵羊

文章 0 评论 0

瞳孔里扚悲伤

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文