目录
Jackson 概述 与 依赖
Jackson 使用前情提要
ObjectMapper 序列化对象
JsonNode 树模型 Json 节点
Jsonson 注解设置 POJO 属性
1、市面上用于在 Java 中解析 Json 的第三方库,随便一搜不下几十种,其中的佼佼者有 Google 的 Gson, Alibaba 的 Fastjson 以及本文的 jackson。
2、三者不相伯仲,随着掌握一个都能满足项目中的 json 解析操作,因为 Spring Boot Web 组件默认使用的是 jackson,所以掌握 Jackjson 是非常有必要的。
3、gson 和 fastjson 使用时只需要导入一个 jar 包(或者一个依赖)即可,而 jackson 却不是全部集成在一个 jar (一个应用)内,而是分为不同的功能模块,需要使用哪些功能,则导入对应的 jar 包(或依赖)。
FasterXml Github 地址:https://github.com/FasterXML,jackson 所有的功能模块都在其中 比如 jackson-core 模块:https://github.com/FasterXML/jackson-core,其中提供了 maven 依赖: |
com.fasterxml.jackson.core
jackson-core
${jackson.version.core}
jackson-core 二进制 jar 包下载地址:http://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/ 其余的 jackson-xxx 模块也是同理,在其相应的项目主页中,都提供 maven 依赖与下载 jar 地址。 |
4、看了上面 Spring Boot Web 组件依赖 jackson 的情况就知道,使用 Jackson 导入以下 3 个主要模块基本满足开发:
jackson-core #maven 依赖、二进制jar包 jackson-annotations #maven依赖、二进制jar包 jackson-databind #maven依赖、二进制jar包 |
5、其中 jackson-databind 内部依赖了 jackson-annotations 与 jackson-core,所以 Maven 应用时,只要导入 databind 一个,则同时也导入了 annotations 与 core 依赖。
com.fasterxml.jackson.core
jackson-databind
2.11.0
1、默认情况下,ObjectMapper 在序列化对象时,将实体所有的字段一 一序列化,无论这些字段是否有值,是否为 null。
2、如果实体的某个字段没有提供 getter 方法,则该字段不会被序列化。
3、Spring Boot Web 组件默认使用 jackson 进行对象的序列化与反序列化,即页面传入的参数,会自动反序列化为后台对象,后台传给前端的对象,也会序列化后输出。所以需要注意返回给页面的对象默认不能使用 Jackson 以外的 Json 库序列化,比如返回一个 Gson 的 JsonObject 给前端,则会报错,因为显然 Jackson 序列化时会失败。
4、Jackson 提供三种不同的方法来操作 JSON:
1)流式API - 使用 Stream(流) 的方式对 Json 的每一个组成部分进行最细粒度的控制,JsonParser 读取数据,JsonGenerator 写入数据。 2)树模型 - 将 JSON 文件在内存里以树的形式表示,通过 JsonNode 处理单个Json节点,类似于 XML 的 DOM 解析器。(常用) 3)databind 模块 - ObjectMapper 读/写 JSON 是 POJO 序列化与反序列化 json 最方便的方式。(常用) |
1、ObjectMapper 主要用于对 Java 对象(比如 POJO、List、Set、Map 等等)进行序列化与反序列化。
2、ObjectMapper 除了能在 json 字符串与 Java 对象之间进行转换,还能将 json 字符串与 JsonNode 进行转换。
Java 对象与 Json 字符串的转换 | |
String writeValueAsString(Object value) | 1、用于将任何 Java 对象(如 POJO、List、Set、Map等)序列化为 json 字符串,如果对象中某个属性的值为 null,则默认也会序列化为 null; 2、如果 value 为 null,返回序列化的结果也返回 null |
byte[] writeValueAsBytes(Object value) |
将 java 对象序列化为 字节数组 |
writeValue(File resultFile, Object value) |
将 java 对象序列化并输出指定文件中 |
writeValue(OutputStream out, Object value) |
将 java 对象序列化并输出到指定字节输出流中 |
writeValue(Writer w, Object value) |
将 java 对象序列化并输出到指定字符输出流中 |
T readValue(String content, Class |
1、从给定的 JSON 字符串反序列化为 Java 对象; 2、content 为空或者为 null,都会报错 |
T readValue(byte[] src, Class |
将 json 内容的字节数组反序列化为 java 对象 |
T readValue(File src, Class |
将本地 json 内容的文件反序列化为 java 对象 |
T readValue(InputStream src, Class |
将 json 内容的字节输入流反序列化为 java 对象 |
T readValue(Reader src, Class |
将 json 内容的字符输入流反序列化为 java 对象 |
T readValue(URL src, Class |
通过网络 url 地址将 json 内容反序列化为 java 对象 |
Json 字符串内容反序列化为 Json 节点对象 | |
JsonNode readTree(String content) | 将 JSON 字符串反序列化为 JsonNode 对象,即 json 节点对象 |
JsonNode readTree(URL source) | 对网络上的 json 文件进行反序列化为 json 节点对象 |
JsonNode readTree(InputStream in) | 对 json 文件输入流进行反序列化为 json 节点对象 |
JsonNode readTree(byte[] content) | 对 json 字节数组反序列化为 json 节点对象 |
JsonNode readTree(File file) | 将本地 json 文件反序列为为 json 节点对象 |
Java 对象与 Json 节点对象的转换 | |
T convertValue(Object fromValue, Class |
将 Java 对象(如 POJO、List、Map、Set 等)序列化为 Json 节点对象。 |
T treeToValue(TreeNode n, Class |
json 树节点对象转 Java 对象(如 POJO、List、Set、Map 等等) TreeNode 树节点是整个 json 节点对象模型的根接口。 |
API 演示源码:/src/main/java/com/wmx/jackson/ObjectMapperTest.java
1、JsonNode 表示 json 节点,整个节点模型的根接口为 TreeNode,json 节点主要用于手动构建 json 对象。
2、JsonNode 有各种数据类型的实现类,其中最常用的就是 ObjectNode 与 ArrayNode,前者表示 json 对象,后者表示 json 对象数组。
3、json 节点对象可以通过 JsonNodeFactory 创建,如 JsonNodeFactory.instance.objectNode();
JsonNode json节点通用方法 | |
JsonNode get(String fieldName) | 用于访问对象节点的指定字段的值,如果此节点不是对象、或没有指定字段名的值,或没有这样名称的字段,则返回 null。 |
JsonNode get(int index)JsonNode get(int index) | 访问数组节点的指定索引位置上的值,对于其他节点,总是返回 null. 如果索引小于0,或等于、大于节点大小,则返回 null,对于任何索引都不会引发异常。 |
boolean isArray() | 判断此节点是否为 {@link ArrayNode} 数组节点 |
boolean isObject() | 如果此节点是对象节点,则返回 true,否则返回 false |
int size() | 获取 json 节点的大小,比如 json 对象中有多少键值对,或者 json 数组中有多少元素。 |
ObjectNode deepCopy() | json 节点对象深度复制,相当于克隆 |
Iterator |
获取 json 对象中的所有 key |
Iterator |
如果该节点是JSON数组或对象节点,则访问此节点的所有值节点,对于对象节点,不包括字段名(键),只包括值,对于其他类型的节点,返回空迭代器。 |
boolean has(int index) | 检查此节点是否为数组节点,并是否含有指定的索引。 |
boolean has(String fieldName) |
检查此节点是否为 JSON 对象节点并包含指定属性的值。 |
将 json 属性的值转为 java 数据类型 | |
int asInt() |
asInt():尝试将此节点的值转换为 int 类型,布尔值 false 转换为 0,true 转换为 1。如果不能转换为 int(比如值是对象或数组等结构化类型),则返回默认值 0 ,不会引发异常。 asInt(int defaultValue):设置默认值 |
boolean asBoolean() |
尝试将此节点的值转换为 Java 布尔值,0以外的整数映射为true,0映射为false,字符串“true”和“false”映射到相应的值。 如果无法转换为布尔值(包括对象和数组等结构化类型),则返回默认值 false,不会引发异常。 可以自己设置默认值。 |
asText(String defaultValue) String asText() |
如果节点是值节点(isValueNode 返回 true),则返回容器值的有效字符串表示形式,否则返回空字符串。 |
long asLong() long asLong(long defaultValue) |
与 asInt 同理 |
double asDouble() |
尝试将此节点的值转换为 double,布尔值转换为0.0(false)和1.0(true),字符串使用默认的Java 语言浮点数解析规则进行解析。 如果表示不能转换为 double(包括对象和数组等结构化类型),则返回默认值 0.0,不会引发异常。 |
BigInteger bigIntegerValue() | 返回此节点的整数值(BigDecimal),当且仅当此节点为数字时(isNumber}返回true)。 对于其他类型,返回 BigInteger.ZERO。 |
boolean booleanValue() | 用于访问 JSON 布尔值(值文本“true”和“false”)的方法,对于其他类型,始终返回false |
BigDecimal decimalValue() | 返回此节点的浮点值 BigDecimal, 当且仅当此节点为数字时(isNumber 返回true),对于其他类型,返回 BigDecimal.ZERO |
double doubleValue() | 返回此节点的64位浮点(双精度)值,当且仅当此节点为数字时(isNumber返回true),对于其他类型,返回0.0。 |
float floatValue() | 返回此节点的32位浮点值,当且仅当此节点为数字时(isNumber返回true),对于其他类型,返回0.0。 |
int intValue() long longValue() Number numberValue() short shortValue() String textValue() |
返回此节点的 int、long、Number、short、String 值。 |
ObjectNode 对象节点常用方法 | |
ObjectNode put(String fieldName, String v) |
1、将字段的值设置为指定的值,如果字段已经存在,则更新值,value 可以为 null. 2、其它 8 种基本数据类型以及 String、BigDecimal、BigInteger 都可以 put,但是没有 Date 类型 3、Date 日期类型只能通过 Long 长整型设置 |
ArrayNode putArray(String fieldName) | 构造新的 ArrayNode 子节点,并将其作为此 ObjectNode 的字段添加。 |
ObjectNode putNull(String fieldName): | 为指定字段添加 null 值,put |
ObjectNode putObject(String fieldName) | 构造新的 ObjectNode 字节的,并将其作为此 ObjectNode 的字段添加。 |
替换与删除元素 | |
JsonNode replace(String fieldName, JsonNode value) | 将特定属性的值替换为传递的值,字段存在时更新,不存在时新增 |
JsonNode set(String fieldName, JsonNode value) | 设置指定属性的值为 json 节点对象,字段存在时更新,不存在时新增,类似 replace 方法 |
JsonNode setAll(Map |
同时设置多个 json 节点 |
JsonNode setAll(ObjectNode other) | 添加给定对象(other)的所有属性,重写这些属性的任何现有值. |
ArrayNode withArray(String propertyName) | 将 json 节点转为 json 数组对象 |
ObjectNode with(String propertyName) | 将 json 节点转为 ObjectNode 对象 |
JsonNode remove(String fieldName) | 删除指定的 key,返回被删除的节点 |
ObjectNode remove(Collection |
同时删除多个字段 |
ObjectNode removeAll() | 删除所有字段属性 |
JsonNode without(String fieldName): | 删除指定的 key,底层也是 remove |
ObjectNode without(Collection |
同时删除多个字段,底层也是 removeAll |
ArrayNode 数组节点常用方法 | |
ArrayNode add(String v) | 将指定的字符串值添加到此 json 数组的末尾,其它数据类型也是同理。 除了可以添加 String 类型,还有 Java 的 8 种基本数据类型,以及 BigDecimal、BigInteger、JsonNode 类型。 |
ArrayNode addAll(ArrayNode other) | 用于添加给定数组的所有子节点 |
ArrayNode addNull() | 该方法将在此数组节点的末尾添加 null 值。 |
ArrayNode addArray() | 构造新的 ArrayNode 子节点,并将其添加到此数组节点的末尾 |
ObjectNode addObject() | 构造一个新的 ObjectNode 字节的,并将其添加到此数组节点的末尾 |
API 演示源码:/src/main/java/com/wmx/jackson/JsonNodeTest.java
1、ObjectMapper 序列化 POJO 对象为 json 字符串时,Date 日期类型默认会转为 long 长整型,json 字符串反序列化为 POJO 时自动将长整型的日期转为 Date 类型。
2、Map 对象序列化为 json 字符串时,Map 中的日期值也会默认转为 long 长整型, ObjectMapper.readValue(String content, Class
3、JsonNode 节点对象 put 数据时,有 8 种基本数据类型以及 String、BigDecimal、BigInteger,但是没有 Date 类型,所以日期类型只能通过 Long 长整型设置,但是转 POJO 对象时仍然会自动转为 Date 类型。
4、Google 的 gson 默认不会序列化对象中值为 null 的字段,而 jackson 则不管值是否为 null,都会序列化。
5、@JsonFormat 注解加到指定对象的属性上可以指定日期序列化的格式。
6、JsonInclude(JsonInclude.Include.NON_NULL) 添加到 POJO 对象上,表示对值为 null 的属性不进行序列化。
API 演示源码:
https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/jackson/Book.java
https://github.com/wangmaoxiong/apache-study/blob/master/src/main/java/com/wmx/jackson/AnnotationTest.java