Jackson API 详细汇总 与 使用介绍
Jackson 概述 与 依赖
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 依赖: |
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <!-- 如可以使用最新的 2.9.7、2.9.8 版本 --> <version>${jackson.version.core}</version> </dependency>
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 个主要模块基本满足开发:
5、其中 jackson-databind 内部依赖了 jackson-annotations 与 jackson-core,所以 Maven 应用时,只要导入 databind 一个,则同时也导入了 annotations 与 core 依赖。
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.0</version> </dependency>
Jackson 使用前情提要
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 最方便的方式。(常用) |
ObjectMapper 序列化对象
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<T> valueType) |
1、从给定的 JSON 字符串反序列化为 Java 对象; 2、content 为空或者为 null,都会报错 |
T readValue(byte[] src, Class<T> valueType) | 将 json 内容的字节数组反序列化为 java 对象 |
T readValue(File src, Class<T> valueType) | 将本地 json 内容的文件反序列化为 java 对象 |
T readValue(InputStream src, Class<T> valueType) | 将 json 内容的字节输入流反序列化为 java 对象 |
T readValue(Reader src, Class<T> valueType) | 将 json 内容的字符输入流反序列化为 java 对象 |
T readValue(URL src, Class<T> valueType) |
通过网络 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<T> toValueType) | 将 Java 对象(如 POJO、List、Map、Set 等)序列化为 Json 节点对象。 |
T treeToValue(TreeNode n, Class<T> valueType) |
json 树节点对象转 Java 对象(如 POJO、List、Set、Map 等等) TreeNode 树节点是整个 json 节点对象模型的根接口。 |
API 演示源码:/src/main/java/com/wmx/jackson/ObjectMapperTest.java
package com.wmx.jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Test; import javax.swing.filechooser.FileSystemView; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.net.URL; import java.util.*; /** * {@link ObjectMapper} 用于对 Java 对象(比如 POJO、List、Set、Map 等等)进行序列化与反序列化 * * @author wangMaoXiong * @version 1.0 * @date 2020/7/16 14:34 */ @SuppressWarnings("all") public class ObjectMapperTest { /** * POJO 对象转 json 字符串 * String writeValueAsString(Object value) * 1、该方法可用于将任何 Java 值、对象序列化为 json 字符串,如果对象中某个属性的值为 null,则默认也会序列化为 null * 2、value 为 null,返回 null * * @throws JsonProcessingException */ @Test public void writeValueAsString1() throws JsonProcessingException { User user = new User(1000, "张三", new Date(), null); ObjectMapper objectMapper = new ObjectMapper(); String json = objectMapper.writeValueAsString(user); System.out.println(json); //{"uId":1000,"uName":"张三","birthday":1594881355832,"price":null} } /** * String writeValueAsString(Object value) * 1、 Java 值、对象序列化为 json 字符串,value 可以是任意的 java 对象,比如 POJO、list、Map、Set 等等 */ @Test public void writeValueAsString2() { try { List<User> userList = new ArrayList<>(2); User user1 = new User(1000, "张三", null, 7777.88F); User user2 = new User(2000, "李四", new Date(), 9800.78F); userList.add(user1); userList.add(user2); ObjectMapper objectMapper = new ObjectMapper(); String json = objectMapper.writeValueAsString(userList); //[{"uId":1000,"uName":"张三","birthday":null,"price":7777.88},{"uId":2000,"uName":"李四","birthday":1594882217908,"price":9800.78}] System.out.println(json); } catch (IOException e) { e.printStackTrace(); } } /** * String writeValueAsString(Object value) * 1、 Java 值、对象序列化为 json 字符串,value 可以是任意的 java 对象,比如 POJO、list、Map、Set 等等 */ @Test public void writeValueAsString3() throws JsonProcessingException { try { Map<String, Object> dataMap = new HashMap<>(); dataMap.put("uId", 9527); dataMap.put("uName", "华安"); dataMap.put("birthday", new Date()); dataMap.put("price", 9998.45F); dataMap.put("marry", null); ObjectMapper objectMapper = new ObjectMapper(); //{"birthday":1594884443501,"uId":9527,"uName":"华安","price":9998.45,"marry":null} String json = objectMapper.writeValueAsString(dataMap); System.out.println(json); } catch (IOException e) { e.printStackTrace(); } } /** * writeValue(File resultFile, Object value) * 1、 Java java 对象,比如 POJO、list、Map、Set 等等 序列化并输出到指定文件中 * 2、文件不存在时,会自动新建 */ @Test public void writeValueAsString4() throws JsonProcessingException { try { Map<String, Object> dataMap = new HashMap<>(); dataMap.put("uId", 9527); dataMap.put("uName", "华安2"); dataMap.put("birthday", new Date()); dataMap.put("price", 9998.45F); dataMap.put("marry", null); File homeDirectory = FileSystemView.getFileSystemView().getHomeDirectory(); File jsonFile = new File(homeDirectory, "wmx2.json"); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.writeValue(jsonFile, dataMap); System.out.println("输出 json 文件:" + jsonFile.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } } /** * T readValue(String content, Class<T> valueType) * 1、从给定的 JSON 内容字符串反序列化为对象 * 2、content 为空或者为 null,都会报错 * 3、valueType 表示反序列号的结果对象,可以是任何 java 对象,比如 POJO、List、Set、Map 等等. */ @Test public void readValue1() { try { String json = "{\"uId\":1000,\"uName\":\"张三\",\"birthday\":1594881355832,\"price\":null}"; ObjectMapper objectMapper = new ObjectMapper(); User user = objectMapper.readValue(json, User.class); //User{uId=1000, uName='张三', birthday=Thu Jul 16 14:35:55 CST 2020, price=null} System.out.println(user); } catch (IOException e) { e.printStackTrace(); } } /** * T readValue(String content, Class<T> valueType) * 1、从给定的 JSON 内容字符串反序列化为对象 * 2、content 为空或者为 null,都会报错 * 3、valueType 表示反序列号的结果对象,可以是任何 java 对象,比如 POJO、List、Set、Map 等等. */ @Test public void readValue2() { try { String json = "[{\"uId\":1000,\"uName\":\"张三\",\"birthday\":null,\"price\":7777.88},{\"uId\":2000,\"uName\":\"李四\",\"birthday\":1594882217908,\"price\":9800.78}]"; ObjectMapper objectMapper = new ObjectMapper(); List<User> userList = objectMapper.readValue(json, List.class); //{uId=2000, uName=李四, birthday=1594882217908, price=9800.78} System.out.println(userList.get(1)); } catch (IOException e) { e.printStackTrace(); } } /** * T readValue(String content, Class<T> valueType) * 1、从给定的 JSON 内容字符串反序列化为对象 * 2、content 为空或者为 null,都会报错 * 3、valueType 表示反序列号的结果对象,可以是任何 java 对象,比如 POJO、List、Set、Map 等等. */ @Test public void readValue3() { try { String json = "{\"birthday\":1594884443501,\"uId\":9527,\"uName\":\"华安\",\"price\":9998.45,\"marry\":null}"; ObjectMapper objectMapper = new ObjectMapper(); Map map = objectMapper.readValue(json, Map.class); //{birthday=1594884443501, uId=9527, uName=华安, price=9998.45, marry=null} System.out.println(map); } catch (IOException e) { e.printStackTrace(); } } /** * T readValue(File src, Class<T> valueType):将本地 json 内容文件反序列为 Java 对象 */ @Test public void readTree4() { try { String json = "[{\"uId\":1000,\"uName\":\"张三\",\"birthday\":null,\"price\":7777.88},{\"uId\":2000,\"uName\":\"李四\",\"birthday\":1594882217908,\"price\":9800.78}]"; File homeDirectory = FileSystemView.getFileSystemView().getHomeDirectory(); File jsonFile = new File(homeDirectory, "wmx.json"); if (!jsonFile.exists()) { FileWriter fileWriter = new FileWriter(jsonFile); fileWriter.write(json); fileWriter.flush(); fileWriter.close(); System.out.println("输出 json 文件:" + jsonFile.getAbsolutePath()); } List<User> userList = new ObjectMapper().readValue(jsonFile, List.class); //{uId=2000, uName=李四, birthday=1594882217908, price=9800.78} System.out.println(userList.get(1)); } catch (Exception e) { e.printStackTrace(); } } /** * JsonNode readTree(String content):将 JSON 内容反序列化为 JsonNode 对象 * * @throws IOException */ @Test public void readTree1() throws IOException { //被解析的 json 格式的字符串 String json = "{\"notices\":[{\"title\":\"停水\",\"day\":\"1\"},{\"title\":\"停电\",\"day\":\"3\"},{\"title\":\"停网\",\"day\":\"2\"}]}"; ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readTree(json); System.out.println(jsonNode); } /** * JsonNode readTree(URL source) :对网络上的 json 文件进行反序列化为 json 节点对象 */ @Test public void readTree2() { try { URL url = new URL("http://t.weather.sojson.com/api/weather/city/101030100"); JsonNode jsonNode = new ObjectMapper().readTree(url); System.out.println(jsonNode); } catch (Exception e) { e.printStackTrace(); } } /** * JsonNode readTree(File file):将本地 json 文件反序列化为 json 节点对象 */ @Test public void readTree3() { try { String json = "[{\"uId\":1000,\"uName\":\"张三\",\"birthday\":null,\"price\":7777.88},{\"uId\":2000,\"uName\":\"李四\",\"birthday\":1594882217908,\"price\":9800.78}]"; File homeDirectory = FileSystemView.getFileSystemView().getHomeDirectory(); File jsonFile = new File(homeDirectory, "wmx.json"); if (!jsonFile.exists()) { FileWriter fileWriter = new FileWriter(jsonFile); fileWriter.write(json); fileWriter.flush(); fileWriter.close(); System.out.println("输出 json 文件:" + jsonFile.getAbsolutePath()); } JsonNode jsonNode = new ObjectMapper().readTree(jsonFile); System.out.println(jsonNode.get(0));//{"uId":1000,"uName":"张三","birthday":null,"price":7777.88} } catch (Exception e) { e.printStackTrace(); } } /** * T treeToValue(TreeNode n, Class<T> valueType):json 节点对象转 Java 对象(如 POJO、List、Set、Map 等等) */ @Test public void test() { try { ObjectNode objectNode = JsonNodeFactory.instance.objectNode(); objectNode.put("uId", 3200); objectNode.put("uName", "李世民"); objectNode.put("birthday", new Date().getTime()); User user = new ObjectMapper().treeToValue(objectNode, User.class); //User{uId=3200, uName='李世民', birthday=Fri Jul 17 20:34:13 CST 2020, price=null} System.out.println(user); } catch (JsonProcessingException e) { e.printStackTrace(); } } /** * T convertValue(Object fromValue, Class<T> toValueType) * 1、将 Java 对象(如 POJO、List、Map、Set 等)序列化为 Json 节点对象,通常有以下两种方式: * 2、一种方式是先序列化为 json 字符串,然后 readTree 反序列化为 Json 节点 * 3、还有就是使用此种方式进行转换,将 java 对象直接转换为 json 节点。 */ @Test public void convertValue1() { User user = new User(1000, "张三", new Date(), null); ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.convertValue(user, JsonNode.class); //{"uId":1000,"uName":"张三","birthday":1594967015825,"price":null} System.out.println(jsonNode); } @Test public void convertValue2() { Map<String, Object> dataMap = new HashMap<>(); dataMap.put("uId", 9527); dataMap.put("uName", "华安"); dataMap.put("birthday", new Date()); dataMap.put("price", 9998.45F); dataMap.put("marry", null); ObjectMapper objectMapper = new ObjectMapper(); JsonNode objectNode = objectMapper.convertValue(dataMap, JsonNode.class); //{"birthday":1594950930586,"uId":9527,"uName":"华安","price":9998.45,"marry":null} System.out.println(objectNode); } @Test public void convertValue3() { List<User> userList = new ArrayList<>(2); User user1 = new User(1000, "张三", null, 7777.88F); User user2 = new User(2000, "李四", new Date(), 9800.78F); userList.add(user1); userList.add(user2); ObjectMapper objectMapper = new ObjectMapper(); JsonNode objectNode = objectMapper.convertValue(userList, JsonNode.class); //[{"uId":1000,"uName":"张三","birthday":null,"price":7777.88},{"uId":2000,"uName":"李四","birthday":1594967168878,"price":9800.78}] System.out.println(objectNode); } }
JsonNode 树模型 Json 节点
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<String> fieldNames() | 获取 json 对象中的所有 key |
Iterator<JsonNode> elements() | 如果该节点是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<String,? extends JsonNode> properties) | 同时设置多个 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<String> fieldNames) | 同时删除多个字段 |
ObjectNode removeAll() | 删除所有字段属性 |
JsonNode without(String fieldName): | 删除指定的 key,底层也是 remove |
ObjectNode without(Collection<String> fieldNames) | 同时删除多个字段,底层也是 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
package com.wmx.jackson; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.NumericNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Test; import java.io.IOException; import java.math.BigDecimal; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * {@link ArrayNode}、{@link ObjectNode}、{@link NumericNode} 等等都是 {@link JsonNode} 的子类 * * @author wangMaoXiong * @version 1.0 * @date 2020/7/16 16:57 */ @SuppressWarnings("all") public class JsonNodeTest { /** * JsonNodeFactory.instance: 创建单例的 JsonNodeFactory 工厂 * ObjectNode objectNode() : 构造空的 JSON 对象 * ObjectNode put(String fieldName, String v): 将字段的值设置为指定的字符串值,如果字段已经存在,则更新值 * ObjectNode put(String fieldName, int v):其它数据类型也是同理 * ArrayNode putArray(String fieldName):构造 ArrayNode 并将其作为此 ObjectNode 的字段添加。 * ObjectNode putNull(String fieldName): 为指定字段添加 null 值 * ArrayNode add(String v) :将指定的字符串值添加到此数组的末尾,其它数据类型也是同理。 */ @Test public void objectNode1() { JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance; ObjectNode objectNode = jsonNodeFactory.objectNode(); objectNode.put("name", "张三"); objectNode.put("age", 25); objectNode.putNull("marry"); ArrayNode arrayNode = objectNode.putArray("urls"); arrayNode.add("http://tomcat.org/tomcat.png#1"); arrayNode.add("http://tomcat.org/tomcat.png#2"); arrayNode.add("http://tomcat.org/tomcat.png#3"); //{"name":"张三","age":25,"marry":null,"urls":["http://tomcat.org/tomcat.png#1","http://tomcat.org/tomcat.png#2","http://tomcat.org/tomcat.png#3"]} System.out.println(objectNode.toString()); } @Test public void objectNode2() { JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance; ObjectNode objectNode_root = jsonNodeFactory.objectNode(); ArrayNode arrayNode = objectNode_root.putArray("notices"); ObjectNode objectNodeChild = jsonNodeFactory.objectNode(); objectNodeChild.put("title", "放假通知"); objectNodeChild.put("content", "寒假放假于本月3浩开始."); arrayNode.add(objectNodeChild); //{"notices":[{"title":"放假通知","content":"寒假放假于本月3浩开始."}]} System.out.println(objectNode_root); } /** * JsonNode replace(String fieldName, JsonNode value):将特定属性的值替换为传递的值,字段存在时更新,不存在时新增 * JsonNode set(String fieldName, JsonNode value):设置指定属性的值为 json 节点对象,字段存在时更新,不存在时新增,类似 replace 方法 * JsonNode setAll(Map<String,? extends JsonNode> properties):同时设置多个 json 节点 */ @Test public void objectNode3() { try { String json = "{\"notices\":[{\"title\":\"放假通知\",\"content\":\"寒假放假于本月3浩开始.\"}]}"; JsonNode jsonNode = new ObjectMapper().readTree(json); ObjectNode objectNode = (ObjectNode) jsonNode; ObjectNode node = JsonNodeFactory.instance.objectNode(); node.put("code", 200); objectNode.set("status", node); //{"notices":[{"title":"放假通知","content":"寒假放假于本月3浩开始."}],"status":{"code":200}} System.out.println(objectNode); } catch (IOException e) { e.printStackTrace(); } } /** * JsonNode setAll(ObjectNode other):添加给定对象(other)的所有属性,重写这些属性的任何现有值 */ @Test public void objectNode4() { try { String json = "{\"notices\":[{\"title\":\"放假通知\",\"content\":\"寒假放假于本月3浩开始.\"}]}"; JsonNode jsonNode = new ObjectMapper().readTree(json); ObjectNode objectNode = (ObjectNode) jsonNode; ObjectNode node = JsonNodeFactory.instance.objectNode(); node.put("code", 200); objectNode.setAll(node); //{"notices":[{"title":"放假通知","content":"寒假放假于本月3浩开始."}],"code":200} System.out.println(objectNode); } catch (IOException e) { e.printStackTrace(); } } /** * JsonNode get(String fieldName): * 1、用于访问对象节点的指定字段的值,如果此节点不是对象、或没有指定字段名的值,或没有这样名称的字段,则返回 null。 * boolean isArray(): 判断此节点是否为 {@link ArrayNode} 数组节点 * int size():获取数组节点的大小 * int asInt(): * 1、尝试将此节点的值转换为 int 类型,布尔值 false 转换为 0,true 转换为 1。 * 2、如果不能转换为 int(比如值是对象或数组等结构化类型),则返回默认值 0 ,不会引发异常。 * String asText():如果节点是值节点(isValueNode返回true),则返回容器值的有效字符串表示形式,否则返回空字符串。 * 其它数据类型也是同理 */ @Test public void objectNode5() { try { String json = "{\"notices\":[{\"title\":\"停水\",\"day\":\"12\"},{\"title\":\"停电\",\"day\":\"32\"},{\"title\":\"停网\",\"day\":\"22\"}]}"; ObjectMapper objectMapper = new ObjectMapper(); ObjectNode jsonNode = (ObjectNode) objectMapper.readTree(json); JsonNode notices = jsonNode.get("notices"); if (notices != null && notices.isArray()) { for (int i = 0; i < notices.size(); i++) { JsonNode childNode = notices.get(i); String title = childNode.get("title").asText(); Integer day = childNode.get("day").asInt(); System.out.println((i + 1) + ":" + title + "\t" + day); } } } catch (IOException e) { e.printStackTrace(); } } /** * ArrayNode withArray(String propertyName): 将 json 节点转为 json 数组对象 * ObjectNode with(String propertyName):将 json 节点转为 ObjectNode 对象 */ @Test public void objectNode6() { try { String json = "{\"notices\":[{\"title\":\"放假通知\",\"content\":\"寒假放假于本月3浩开始.\"}]}"; JsonNode jsonNode = new ObjectMapper().readTree(json); ObjectNode objectNode = (ObjectNode) jsonNode; ArrayNode arrayNode = objectNode.withArray("notices"); for (int i = 0; i < arrayNode.size(); i++) { //{"title":"放假通知","content":"寒假放假于本月3浩开始."} JsonNode node = arrayNode.get(i); System.out.println(node); } } catch (IOException e) { e.printStackTrace(); } } /** * JsonNode remove(String fieldName):删除指定的 key,返回被删除的节点 * JsonNode without(String fieldName): * ObjectNode remove(Collection<String> fieldNames):同时删除多个字段 * ObjectNode without(Collection<String> fieldNames):同时删除多个字段 * ObjectNode removeAll(): 删除所有字段属性 */ @Test public void objectNode7() { try { String json = "{\"notices\":[{\"title\":\"放假通知\",\"content\":\"寒假放假于本月3浩开始.\"}]}"; JsonNode jsonNode = new ObjectMapper().readTree(json); ObjectNode objectNode = (ObjectNode) jsonNode; JsonNode remove = objectNode.remove("notices"); System.out.println(remove);//[{"title":"放假通知","content":"寒假放假于本月3浩开始."}] System.out.println(objectNode);//{} } catch (IOException e) { e.printStackTrace(); } } /** * ObjectNode deepCopy():json 节点对象深度复制,相当于克隆 * Iterator<String> fieldNames(): 获取 json 对象中的所有 key */ @Test public void objectNode8() { try { String json = "{\"title\":\"放假通知\",\"content\":\"寒假放假于本月3浩开始.\"}"; JsonNode jsonNode = new ObjectMapper().readTree(json); ObjectNode objectNode = (ObjectNode) jsonNode; ObjectNode deepCopy = objectNode.deepCopy(); deepCopy.put("summary", "同意"); System.out.println(objectNode);//{"title":"放假通知","content":"寒假放假于本月3浩开始."} System.out.println(deepCopy);//{"title":"放假通知","content":"寒假放假于本月3浩开始.","summary":"同意"} Iterator<String> fieldNames = deepCopy.fieldNames(); while (fieldNames.hasNext()) { String next = fieldNames.next(); System.out.println(next + "=" + deepCopy.get(next)); } } catch (IOException e) { e.printStackTrace(); } } @Test public void objectNode9() { Map<String, Object> dataMap = new HashMap<>(); dataMap.put("code", 200); dataMap.put("msg", "成功"); ObjectNode objectNode = JsonNodeFactory.instance.objectNode(); objectNode.putPOJO("data", dataMap); System.out.println(objectNode); JsonNode jsonNode = objectNode.get("data"); } /** * double asDouble(): 尝试将此节点的值转换为 double,布尔值转换为0.0(false)和1.0(true),字符串使用默认的Java 语言浮点数解析规则进行解析。 * 如果表示不能转换为 double(包括对象和数组等结构化类型),则返回默认值 0.0,不会引发异常。 * BigDecimal decimalValue() :返回此节点的浮点值 BigDecimal, 当且仅当此节点为数字时(isNumber 返回true),对于其他类型,返回 BigDecimal.ZERO */ @Test public void test10() { ObjectNode objectNode = JsonNodeFactory.instance.objectNode(); objectNode.put("id", 1000); objectNode.put("salay", 15000.456); double salay = objectNode.get("salay").asDouble(); BigDecimal bigDecimal = objectNode.get("salay").decimalValue(); System.out.println(salay + "," + bigDecimal);//15000.456,15000.456 } /** * boolean has(int index):检查此节点是否为数组节点,并是否含有指定的索引。 * boolean has(String fieldName):检查此节点是否为 JSON 对象节点并包含指定属性的值。 */ @Test public void test11() { ArrayNode arrayNode = JsonNodeFactory.instance.arrayNode(); arrayNode.add(12).add("中国").addNull().add(345.5667); System.out.println(arrayNode);//[12,"中国",null,345.5667] System.out.println(arrayNode.has(1));//true System.out.println(arrayNode.has(2));//true System.out.println(arrayNode.has(4));//false } /** * Iterator<JsonNode> elements():如果该节点是JSON数组或对象节点,则访问此节点的所有值节点 * 对于对象节点,不包括字段名(键),只包括值,对于其他类型的节点,返回空迭代器。 */ @Test public void test12() { try { String json = "{\"title\":\"放假通知\",\"content\":\"寒假放假于本月3浩开始.\",\"id\":23400}"; JsonNode jsonNode = new ObjectMapper().readTree(json); Iterator<JsonNode> elements = jsonNode.elements(); while (elements.hasNext()) { JsonNode next = elements.next(); //"放假通知" "寒假放假于本月3浩开始." 23400 System.out.print(next + " "); } } catch (IOException e) { e.printStackTrace(); } } /** * ArrayNode addAll(ArrayNode other): 用于添加给定数组的所有子节点 */ @Test public void test13() { try { String json = "[{\"title\":\"放假通知\",\"content\":\"寒假放假于本月3浩开始.\"}]"; JsonNode jsonNode = new ObjectMapper().readTree(json); ArrayNode rootArrayNode = JsonNodeFactory.instance.arrayNode(); rootArrayNode.add(1000); if (jsonNode.isArray()) { ArrayNode arrayNode = (ArrayNode) jsonNode; rootArrayNode.addAll(arrayNode); } //[1000,{"title":"放假通知","content":"寒假放假于本月3浩开始."}] System.out.println(rootArrayNode); } catch (IOException e) { e.printStackTrace(); } } /** * ArrayNode addNull() :该方法将在此数组节点的末尾添加空值。 */ @Test public void test14() { try { String json = "[{\"title\":\"放假通知\",\"content\":\"寒假放假于本月3浩开始.\"}]"; JsonNode jsonNode = new ObjectMapper().readTree(json); if (jsonNode.isArray()) { ArrayNode arrayNode = (ArrayNode) jsonNode; arrayNode.addNull(); //[{"title":"放假通知","content":"寒假放假于本月3浩开始."},null] System.out.println(arrayNode); } } catch (IOException e) { e.printStackTrace(); } } /** * ArrayNode addArray(): 构造新的 ArrayNode 节点,并将其添加到此数组节点的末尾 */ @Test public void test15() { try { String json = "[{\"title\":\"放假通知\",\"content\":\"寒假放假于本月3浩开始.\"}]"; JsonNode jsonNode = new ObjectMapper().readTree(json); if (jsonNode.isArray()) { ArrayNode arrayNode = (ArrayNode) jsonNode; ArrayNode addArray = arrayNode.addArray(); addArray.add(31.4F); addArray.add("优秀"); //[{"title":"放假通知","content":"寒假放假于本月3浩开始."},[31.4,"优秀"]] System.out.println(arrayNode); //[31.4,"优秀"] System.out.println(addArray); } } catch (IOException e) { e.printStackTrace(); } } /** * ObjectNode putObject(String fieldName):构造新的 ObjectNode 字节的,并将其作为此 ObjectNode 的字段添加。 */ @Test public void test16() { try { String json = "{\"title\":\"放假通知\",\"content\":\"寒假放假于本月3浩开始.\"}"; JsonNode jsonNode = new ObjectMapper().readTree(json); if (jsonNode.isObject()) { ObjectNode objectNode = (ObjectNode) jsonNode; ObjectNode persons = objectNode.putObject("person"); persons.put("name", "张三"); persons.put("age", 34); //{"title":"放假通知","content":"寒假放假于本月3浩开始.","person":{"name":"张三","age":34}} System.out.println(objectNode); } } catch (IOException e) { e.printStackTrace(); } } }
Jsonson 注解设置 POJO 属性
1、ObjectMapper 序列化 POJO 对象为 json 字符串时,Date 日期类型默认会转为 long 长整型,json 字符串反序列化为 POJO 时自动将长整型的日期转为 Date 类型。
2、Map 对象序列化为 json 字符串时,Map 中的日期值也会默认转为 long 长整型, ObjectMapper.readValue(String content, Class<T> valueType):反序列化为 Map 对象时,长整型的日期仍旧是长整型,不会转回 Date。ObjectMapper.readTree(String content) 反序列化为 json 节点时,原来 Map 中的长整型的日期也会是长整型。
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 的属性不进行序列化。
参考文章:https://blog.csdn.net/wangmx1993328/article/details/88598625