Java之Jackson的基本使用案例讲解

Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架。Jackson 社 区相对比较活跃,更新速度也比较快, 从 Github 中的统计来看,Jackson 是最流行的 json 解析器之一 。 Spring MVC 的默认 json 解析器便是 Jackson。 Jackson 优点很多。 Jackson 所依赖的 jar 包较少 ,简单易用。与其他 Java 的 json 的框架 Gson 等相比, Jackson 解析大的 json 文件速度比较快;Jackson 运行时占用内存比较低,性能比较好;Jackson 有灵活的 API,可以很容易进行扩展和定制。

Jackson 的 1.x 版本的包名是 org.codehaus.jackson ,当升级到 2.x 版本时,包名变为 com.fasterxml.jackson,本文讨论的内容是基于最新的 Jackson 的 2.9.1 版本。

Jackson 的核心模块由三部分组成。

  • jackson-core,核心包,提供基于"流模式"解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。
  • jackson-annotations,注解包,提供标准注解功能;
  • jackson-databind ,数据绑定包, 提供基于"对象绑定" 解析的相关 API ( ObjectMapper ) 和"树模型" 解析的相关 API (JsonNode);基于"对象绑定" 解析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API。
清单 1.在 pom.xml 的 Jackson 的配置信息
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.1</version>
</dependency>

jackson-databind 依赖 jackson-core 和 jackson-annotations,当添加 jackson-databind 之后, jackson-core 和 jackson-annotations 也随之添加到 Java 项目工程中。在添加相关依赖包之后,就可以使用 Jackson。

ObjectMapper 的 使用

Jackson 最常用的 API 就是基于"对象绑定" 的 ObjectMapper。下面是一个 ObjectMapper 的使用的简单示例。

清单 2 . ObjectMapper 使用示例
ObjectMapper mapper = new ObjectMapper();
Person person = new Person();
person.setName("Tom");
person.setAge(40);
String jsonString = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(person);
Person deserializedPerson = mapper.readValue(jsonString, Person.class);

ObjectMapper 通过 writeValue 系列方法 将 java 对 象序列化 为 json,并 将 json 存 储成不同的格式,String(writeValueAsString),Byte Array(writeValueAsString),Writer, File,OutStream 和 DataOutput。

ObjectMapper 通过 readValue 系列方法从不同的数据源像 String , Byte Array, Reader,File,URL, InputStream 将 json 反序列化为 java 对象。

信息配置

在调用 writeValue 或调用 readValue 方法之前,往往需要设置 ObjectMapper 的相关配置信息。这些配置信息应用 java 对象的所有属性上。示例如下:

清单 3 . 配置信息使用示例
//在反序列化时忽略在 json 中存在但 Java 对象不存在的属性
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
   false);
//在序列化时日期格式默认为 yyyy-MM-dd'T'HH:mm:ss.SSSZ
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false)
//在序列化时忽略值为 null 的属性
mapper.setSerializationInclusion(Include.NON_NULL);
//忽略值为默认值的属性
mapper.setDefaultPropertyInclusion(Include.NON_DEFAULT);

更多配置信息可以查看 Jackson 的 DeserializationFeature,SerializationFeature 和 I nclude。

Jackson 的 注解的使用

Jackson 根据它的默认方式序列化和反序列化 java 对象,若根据实际需要,灵活的调整它的默认方式,可以使用 Jackson 的注解。常用的注解及用法如下。

表 1. Jackson 的 常用注解
注解 用法
@JsonProperty 用于属性,把属性的名称序列化时转换为另外一个名称。示例: 
@JsonProperty("birth_ d ate") 
private Date birthDate;
@JsonFormat 用于属性或者方法,把属性的格式序列化时转换成指定的格式。示例: 
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm") 
public Date getBirthDate()
@JsonPropertyOrder 用于类, 指定属性在序列化时 json 中的顺序 , 示例: 
@JsonPropertyOrder({ "birth_Date", "name" }) 
public class Person
@JsonCreator 用于构造方法,和 @JsonProperty 配合使用,适用有参数的构造方法。 示例: 
@JsonCreator 
public Person(@JsonProperty("name")String name) {…}
@JsonAnySetter 用于属性或者方法,设置未反序列化的属性名和值作为键值存储到 map 中 
@JsonAnySetter 
public void set(String key, Object value) { 
map.put(key, value); 
}
@JsonAnyGetter 用于方法 ,获取所有未序列化的属性 
public Map<String, Object> any() { return map; }

 Jackson示例

Jackson ObjectMapper Example

ObjectMapper objectMapper = new ObjectMapper();

String carJson =
    "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";

try {
    Car car = objectMapper.readValue(carJson, Car.class);

    System.out.println("car brand = " + car.getBrand());
    System.out.println("car doors = " + car.getDoors());
} catch (IOException e) {
    e.printStackTrace();
}

public class Car {
    private String brand = null;
    private int doors = 0;

    public String getBrand() { return this.brand; }
    public void   setBrand(String brand){ this.brand = brand;}

    public int  getDoors() { return this.doors; }
    public void setDoors (int doors) { this.doors = doors; }
}

从Reader读取对象

ObjectMapper objectMapper = new ObjectMapper();

String carJson =
        "{ \"brand\" : \"Mercedes\", \"doors\" : 4 }";
Reader reader = new StringReader(carJson);

Car car = objectMapper.readValue(reader, Car.class);

从File中读取对象

ObjectMapper objectMapper = new ObjectMapper();

File file = new File("data/car.json");

Car car = objectMapper.readValue(file, Car.class);

从URL中读取对象

ObjectMapper objectMapper = new ObjectMapper();

URL url = new URL("file:data/car.json");

Car car = objectMapper.readValue(url, Car.class);

从InputStream读取对象

ObjectMapper objectMapper = new ObjectMapper();

InputStream input = new FileInputStream("data/car.json");

Car car = objectMapper.readValue(input, Car.class);

从字节数组中读取对象

ObjectMapper objectMapper = new ObjectMapper();

String carJson =
        "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";

byte[] bytes = carJson.getBytes("UTF-8");

Car car = objectMapper.readValue(bytes, Car.class);

从JSON数组字符串中读取对象数组 

String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";

ObjectMapper objectMapper = new ObjectMapper();

Car[] cars2 = objectMapper.readValue(jsonArray, Car[].class);

从JSON数组字符串中读取对象列表

String jsonArray =“[{\”brand \“:\”ford \“},{\”brand \“:\”Fiat \“}]”;

ObjectMapper objectMapper = new ObjectMapper();

List <Car> cars1 = objectMapper.readValue(jsonArray,new TypeReference <List <Car >>(){});

从JSON字符串中读取映射为map

String jsonObject =“{\”brand \“:\”ford \“,\”doors \“:5}”;

ObjectMapper objectMapper = new ObjectMapper();
Map <String,Object> jsonMap = objectMapper.readValue(jsonObject,
    new TypeReference <Map <String,Object >>(){});

树模型

String carJson =
        "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";

ObjectMapper objectMapper = new ObjectMapper();

try {

    JsonNode jsonNode = objectMapper.readValue(carJson, JsonNode.class);

} catch (IOException e) {
    e.printStackTrace();
}

JSON字符串被解析为JsonNode对象而不是Car对象,只需将JsonNode.class第二个参数传递给readValue()方法而不是Car.class本教程前面的示例中使用的方法。

该ObjectMapper班也有一个特殊的readTree(),它总是返回一个方法 JsonNode。以下是JsonNode使用该ObjectMapper readTree()方法将JSON解析为a的示例:

String carJson =
        "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";

ObjectMapper objectMapper = new ObjectMapper();

try {

    JsonNode jsonNode = objectMapper.readTree(carJson);

} catch (IOException e) {
    e.printStackTrace();
}

JsonNode类

String carJson =
        "{ \"brand\" : \"Mercedes\", \"doors\" : 5," +
        "  \"owners\" : [\"John\", \"Jack\", \"Jill\"]," +
        "  \"nestedObject\" : { \"field\" : \"value\" } }";

ObjectMapper objectMapper = new ObjectMapper();

try {

    JsonNode jsonNode = objectMapper.readValue(carJson, JsonNode.class);

    JsonNode brandNode = jsonNode.get("brand");
    String brand = brandNode.asText();
    System.out.println("brand = " + brand);

    JsonNode doorsNode = jsonNode.get("doors");
    int doors = doorsNode.asInt();
    System.out.println("doors = " + doors);

    JsonNode array = jsonNode.get("owners");
    JsonNode jsonNode = array.get(0);
    String john = jsonNode.asText();
    System.out.println("john  = " + john);

    JsonNode child = jsonNode.get("nestedObject");
    JsonNode childField = child.get("field");
    String field = childField.asText();
    System.out.println("field = " + field);

} catch (IOException e) {
    e.printStackTrace();
}

将Object转换为JsonNode

ObjectMapper objectMapper = new ObjectMapper();

Car car = new Car();
car.brand = "Cadillac";
car.doors = 4;

JsonNode carJsonNode = objectMapper.valueToTree(car);

将JsonNode转换为Object

ObjectMapper objectMapper = new ObjectMapper();

String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";

JsonNode carJsonNode = objectMapper.readTree(carJson);

Car car = objectMapper.treeToValue(carJsonNode);

使用Jackson ObjectMapper读取和编写YAML

1.示例1(只是yaml字符串和对象的互转,不涉及yaml文件的处理)

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

import java.io.IOException;

public class YamlJacksonExample {

    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

        Employee employee = new Employee("John Doe", "john@doe.com");

        String yamlString = null;
        try {
            yamlString = objectMapper.writeValueAsString(employee);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            // normally, rethrow exception here - or don't catch it at all.
        }

    }
}

该yamlString变量包含Employee在执行此代码后序列化为YAML数据格式的对象。

以下是Employee再次将YAML文本读入对象的示例:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

import java.io.IOException;

public class YamlJacksonExample {

    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

        Employee employee = new Employee("John Doe", "john@doe.com");

        String yamlString = null;
        try {
            yamlString = objectMapper.writeValueAsString(employee);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            // normally, rethrow exception here - or don't catch it at all.
        }

        try {
            Employee employee2 = objectMapper.readValue(yamlString, Employee.class);

            System.out.println("Done");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

2. 示例2 (yaml文件的读取和写入)

 2.1定义Employee实体类

package com.example.jackjson;

import lombok.Data;

/**
 * @author: GuanBin
 * @date: Created in 上午10:18 2020/6/15
 */
@Data
public class Employee {

    public Employee() {
    }

    public Employee(String name, String email) {
        this.name = name;
        this.email = email;
    }

    String name;

    String email;
}

2.2创建要读取的yml EmployeeYaml.yml文件,并初始化一条数据

name: test
email: test@qq.com

2.3创建要写入的yml文件,EmployeeYamlOutput.yml (空文件)

2.4 测试类

package com.example.jackjson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;

import java.io.File;
import java.io.IOException;

/**
 * @author: GuanBin
 * @date: Created in 上午10:17 2020/6/15
 */
public class YamlJacksonExample {
    public static void main(String[] args) {

        try {
            //从yaml文件读取数据
            reaedYamlToEmployee();
            //写入yaml文件
            reaedEmployeeToYaml();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 从yaml文件读取数据
     * @throws IOException
     */
    private static void reaedYamlToEmployee() throws IOException {
        ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
        Employee employee = mapper.readValue(new File("src/test/java/com/example/jackjson/EmployeeYaml.yml"), Employee.class);
        System.out.println(employee.getName() + "********" + employee.getEmail());

    }

    /**
     * 写入yaml文件
     * @throws IOException
     */
    private static void reaedEmployeeToYaml() throws IOException {
        //去掉三个破折号
        ObjectMapper  mapper = new ObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER));
        //禁用掉把时间写为时间戳
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

        Employee employee = new Employee("test2", "999@qq.com");
        mapper.writeValue(new File("src/test/java/com/example/jackjson/EmployeeYamlOutput.yml"), employee);
    }
}

读取文件的打印输出

test********test@qq.com

Process finished with exit code 0

写入文件的输出

参考:

 https://www.ibm.com/developerworks/cn/java/jackson-advanced-application/index.html

http://tutorials.jenkov.com/java-json/jackson-objectmapper.html

https://www.baeldung.com/jackson-yaml

到此这篇关于Java之Jackson的基本使用案例讲解的文章就介绍到这了,更多相关Java之Jackson的基本使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java中Jackson快速入门

    Java生态圈中有很多处理JSON和XML格式化的类库,Jackson是其中比较著名的一个.虽然JDK自带了XML处理类库,但是相对来说比较低级,使用本文介绍的Jackson等高级类库处理起来会方便很多. 引入类库 由于Jackson相关类库按照功能分为几个相对独立的,所以需要同时引入多个类库,为了方便我将版本号单独提取出来设置,相关Gradle配置如下. ext { jacksonVersion = '2.9.5' } dependencies { compile group: 'com.fa

  • Java下利用Jackson进行JSON解析和序列化示例

    Java下常见的Json类库有Gson.JSON-lib和Jackson等,Jackson相对来说比较高效,在项目中主要使用Jackson进行JSON和Java对象转换,下面给出一些Jackson的JSON操作方法. 一.准备工作 首先去官网下载Jackson工具包.Jackson有1.x系列和2.x系列,截止目前2.x系列的最新版本是2.2.3,2.x系列有3个jar包需要下载: jackson-core-2.2.3.jar(核心jar包,下载地址) jackson-annotations-2

  • java jackson 将对象转json时,忽略子对象的某个属性操作

    我就废话不多说了,大家还是直接看代码吧~ //父对象 public class user implements java.io.Serializable { @JsonIgnoreProperties(value={"addressId"})//在解析成json时,忽略子属性的addressId字段 private Address address; private String username; //......... } //子对象 public class Address imp

  • java如何利用FastJSON、Gson、Jackson三种Json格式工具自定义时间序列化

    Java处理JSON数据有三个比较流行的类库FastJSON.Gson和Jackson. Jackson Jackson是由其社区进行维护,简单易用并且性能也相对高些.但是对于复杂的bean转换Json,转换的格式鄙视标准的Json格式.PS:Jackson为Spring MVC内置Json解析工具 Gson Gson是由谷歌公司研发的产品,目前是最全的Json解析工具.完全可以将复杂的类型的Json解析成Bean或者Bean到Json的转换 FastJson Fastjson是一个Java语言

  • Java之Jackson使用案例详解

    序列化 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象. Json是什么? Jason是 JavaScript Object Notation-  JavaScript对象表示法,是一种轻量级数据交换格式.主要用于数据传输,比如说在后端写了一个Java对象,想在其他地方(前端)使用这个对象,就需要转换为Json这种形式进行传输. 1.

  • Jackson优雅序列化Java枚举类过程解析

    1. 前言 在Java开发中我们为了避免过多的魔法值,使用枚举类来封装一些静态的状态代码.但是在将这些枚举的意思正确而全面的返回给前端却并不是那么顺利,我们通常会使用Jackson类库序列化对象为JSON,今天就来讲一个关于使用Jackson序列化枚举的通用性技巧. 2. 通用枚举范式 为了便于统一处理和规范统一的风格,建议指定一个统一的抽象接口,例如: /** * The interface Enumerator. */ public interface Enumerator { /** *

  • Java中常用解析工具jackson及fastjson的使用

    一.maven安装jackson依赖 <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version

  • 详解Java-Jackson使用

    序列化 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象. Json是什么? Jason是 JavaScript Object Notation- JavaScript对象表示法,是一种轻量级数据交换格式.主要用于数据传输,比如说在后端写了一个Java对象,想在其他地方(前端)使用这个对象,就需要转换为Json这种形式进行传输. 1.基

  • Java之Jackson的基本使用案例讲解

    Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架.Jackson 社 区相对比较活跃,更新速度也比较快, 从 Github 中的统计来看,Jackson 是最流行的 json 解析器之一 . Spring MVC 的默认 json 解析器便是 Jackson. Jackson 优点很多. Jackson 所依赖的 jar 包较少 ,简单易用.与其他 Java 的 json 的框架 Gson 等相比, Jackson 解析大的 json 文件速度比较快

  • Java插件扩展机制之SPI案例讲解

    目录 什么是SPI 与 接口类-实现类 提供的RPC 方式有什么区别? 假设我们需要实现RPC,是怎么做的? 那RPC究竟跟SPI什么关系? SPI的应用场景 怎么实现一个SPI? 中间件是怎么实现SPI的? Apollo-Client中的实现 JDBC中的实现 什么是SPI SPI ,全称为 Service Provider Interface,是一种服务发现机制.其为框架提供了一个对外可扩展的能力. 与 接口类-实现类 提供的RPC 方式有什么区别? 传统的接口类实现形式为如下 public

  • Java之SpringBoot集成ActiveMQ消息中间件案例讲解

    ActiveMQ是Apache提供的开源组件,是基于JMS标准的实现组件.下面将利用SpringBoot整合ActiveMQ组件,实现队列消息的发送与接收. 第一步:引入依赖 第二步:修改application.yml文件,进行ActiveMQ的配置 第三步:定义消息消费监听类 第四步:定义消息生产者业务接口 第五步: 定义消息业务实现类 第六步:定义JMS消息发送配置类   第七步:测试发送消息 查看结果: 本文采用ActiveMQ实现了消息的发送与接收处理.每当有消息接收到时,都会自动执行M

  • Java使用elasticsearch基础API使用案例讲解

    1.依赖 我用的是 springboot 2.2.5.RELEASE 版本,这里只贴出主要依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> 2.配置+测试源码 这里根据elasticsearch服务端的地址进行

  • Java之字节码以及优势案例讲解

    一.Java编译器 Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器,.这台虚拟的机器在任何平台上都提供给编译程序一个共同的接口.编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码来将虚拟机代码转换为特定的系统机器码执行.在Java中,这种提供虚拟机理解的代码叫做字节码(即扩展名为 .class的文件),它不面向任何特定的处理器,仅仅只面向虚拟机. 1.利用记事本写一段Java代码 2.将记事本命名为 hello.java 3.cmd+r

  • Java之IO流面试题案例讲解

    一.Java中IO流分为几种? 按照流的流向分,可以分为输入流和输出流: 按照操作单元分,可以分为字节流和字符流(字节流可以读写任何单位的数据,字符流只可以读写txt数据): 按照流的角色分,可以分为节点流和处理流: 二.IO中flush()和close()的区别 close()方法具备刷新功能,在关闭流之前就会先刷新缓冲区,将缓冲区的字节全部刷新到文件上,在关闭流.(close()方法包含一次flush()方法) flush()方法可以刷新,并且刷新之后可以继续写,而close()方法刷新之后

  • Java数据结构 递归之迷宫回溯案例讲解

    问题介绍: 用二维数组表示一个迷宫,设置迷宫起点和终点,输出迷宫中的一条通路 实现思路: 二维数组表示迷宫: 0表示路且未走过.1表示墙.2表示通路,3表示已经走过但走不通 设置寻路方法setWay,传入地图和坐标参数 默认方向策略:下.右.上.左 假定传入的店没有走过且可以走通,将其值置为2,然后向下寻路,也就是将坐标 (i + 1, j) 传入寻路方法中 进行递归寻路,向下移动后,再次按照方向策略进行寻路,即再向下寻路,直到遇到死路,即下右左均走不通(因为将走过的路置为2,故向上也走不通,即

  • Java对文件进行基本操作案例讲解

    File文件类 java.io.File是文件和目录的重要类(JDK6及以前是唯一) 目录也使用File类进行表示 File类与操作系统无关,但会受到操作系统的权限限制 常用方法 createNewFile , delete , exists , getAbsolutePath , getName , getParent , getPath isDirectory , isFile , length , listFiles , mkdir , mkdirs File不涉及到具体的文件内容.只会涉

  • Java之SSM中bean相关知识汇总案例讲解

    bean 的生命周期 对象创建 实例化Bean对象,默认选择无参构造方法,如果只有一个有参构造那么调用有参构造,如果只有多个有参构造那么报错,除非其中一个有参构造添加了@AutoWired注解: 设置Bean的属性: 依赖注入以及判断是否实现了Aware相关接口(BeanNameAware, BeanFactoryAware, ApplicationContextAware) 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用BeanPostProcessor.pos

  • Java之SpringCloudAlibaba Sentinel组件案例讲解

    Sentinel 是什么 随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性. 官网:https://github.com/alibaba/Sentinel 中文官网:https://github.com/alibaba/Sentinel/wiki Sentinel与Hystrix的区别 由于Hystrix不再积极的开发,进入维护阶段,现在越来越多的开发者在项目中使用Spring Cloud Al

随机推荐