Jackson解析Json数据

1.概述

Jackson 和 FastJson 一样,是一个 Java 语言编写的,可以进行 JSON 处理的开源工具库,Jackson 的使用非常广泛,Spring 框架默认使用 Jackson 进行 JSON 处理。

Jackson 有三个核包,分别是 Streaming、Databid、Annotations,通过这些包可以方便的对 JSON 进行操作。

  • Streaming 在 jackson-core 模块。 定义了一些流处理相关的 API 以及特定的 JSON 实现。
  • Annotations 在 jackson-annotations 模块,包含了 Jackson 中的注解。
  • Databind 在 jackson-databind 模块, 在 Streaming 包的基础上实现了数据绑定,依赖于 StreamingAnnotations 包。

得益于 Jackson 高扩展性的设计,有很多常见的文本格式以及工具都有对 Jackson 的相应适配,如 CSV、XML、YAML 等。

2.Jackson Maven 依赖

  在使用 Jackson 时,大多数情况下我们只需要添加 jackson-databind 依赖项,就可以使用 Jackson 功能了,它依赖了下面两个包。

jackson-databind 依赖

  • com.fasterxml.jackson.core:jackson-annotations
  • com.fasterxml.jackson.core:jackson-core
    <dependencies><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.3</version></dependency><dependency><!-- 引入单元测试模块 --><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.8.2</version><scope>test</scope></dependency><dependency><!-- 引入lombok模块 --><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.22</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.0</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>RELEASE</version></dependency></dependencies> 

3.ObjectMapper 对象映射器

  ObjectMapper 是 Jackson 库中最常用的一个类,使用它可以进行 Java 对象和 JSON 字符串之间快速转换。 Jackson 中的 ObjectMapper 就如同 FastJson 中的 JSON 类。

这个类中有一些常用的方法:

  • readValue() 方法可以进行 JSON 的反序列化操作,比如:将字符串、文件流、字节流、字节数组等转换成 Java 对象。
  • writeValue() 方法可以进行 JSON 的序列化操作,可以将 Java 对象转换成 JSON 字符串。

大多数情况下,ObjectMapper 的工作原理是通过 Java Bean 对象的 Get/Set 方法进行转换时映射的,所以正确编写 Java 对象的 Get/Set 方法尤为重要,不过 ObjectMapper 也提供了诸多配置,比如可以通过配置或者注解的形式对 Java 对象和 JSON 字符串之间的转换过程进行自定义。

4.Jackson JSON 基本操作

4.1 Jackson JSON 序列化

编写一个 Person 类,定义三个属性,名称、年龄以及技能, 将 Java 对象(Person)转换成 JSON 字符串。

import lombok.Data;
import java.util.List;
// Person 类
@Data
public class Person {private String name;private Integer age;private List<String> skillList;
}// 将Person转换为Json对象
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import java.util.Arrays;public class PersonTest {ObjectMapper objectMapper = new ObjectMapper();@Testpublic void pojoToJsonString() throws JsonProcessingException {Person person = new Person();person.setName("Ayang");person.setAge(18);person.setSkillList(Arrays.asList("java", "c++"));String json = objectMapper.writeValueAsString(person);System.out.println(json);String expectedJson = "{\"name\":\"Ayang\",\"age\":18,\"skillList\":[\"java\",\"c++\"]}";Assertions.assertEquals(json, expectedJson);}
}
// 输出的 JSON 字符串:
// {"name":"Ayang","age":18,"skillList":["java","c++"]}

4.2 Jackson JSON 反序列化

将Json字符串反序列化为Java对象(Person类)

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;public class PersonTest01 {ObjectMapper objectMapper = new ObjectMapper();@Testpublic void jsonStringToPojo() throws JsonProcessingException {String expectedJson = "{\"name\":\"Ayang\",\"age\":27,\"skillList\":[\"java\",\"c++\"]}";// readValue方法的输入来源可以是很多种:文件/输入数据(字节数组、输入流等)Person person = objectMapper.readValue(expectedJson, Person.class);System.out.println(person);Assertions.assertEquals(person.getName(),"Ayang");Assertions.assertEquals(person.getSkillList().toString(), "[java, c++]");}
}
// 输出结果
// Person(name=Ayang, age=27, skillList=[java, c++])

4.3 JSON 转 List

上面演示 JSON 字符串都是单个对象的,如果 JSON 是一个对象列表那么使用 Jackson 该怎么处理呢? 从 PersonList.json文件读取数据 转换成 List<Person>

[{"name": "aLang","age": 27,"skillList": ["java","c++"]},{"name": "darcy","age": 26,"skillList": ["go","rust"]}
]

具体实现:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;import java.io.File;
import java.io.IOException;
import java.util.List;public class PersonTest02 {ObjectMapper objectMapper = new ObjectMapper();@Testpublic void jsonStringToPojo() throws IOException {File file = new File("src/PersonList.json");List<Person> personList = objectMapper.readValue(file, new TypeReference<List<Person>>() {});for (Person person : personList) {System.out.println(person);}Assertions.assertEquals(personList.size(), 2);Assertions.assertEquals(personList.get(0).getName(), "aLang");Assertions.assertEquals(personList.get(1).getName(), "darcy");}
}
// 输出结果
//Person(name=aLang, age=27, skillList=[java, c++])
//Person(name=darcy, age=26, skillList=[go, rust])

4.4 JSON 转 Map

使用 Jackson 把 JSON 文本转成 Map 对象。

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.Map;public class PersonTest03 {ObjectMapper objectMapper = new ObjectMapper();@Testpublic void jsonStringToPojo() throws IOException {String expectedJson = "{\"name\":\"aLang\",\"age\":27,\"skillList\":[\"java\",\"c++\"]}";Map<String, Object> employeeMap = objectMapper.readValue(expectedJson, new TypeReference<Map>() {});System.out.println(employeeMap.getClass());for (Map.Entry<String, Object> entry : employeeMap.entrySet()) {System.out.println(entry.getKey() + ":" + entry.getValue());}Assertions.assertEquals(employeeMap.get("name"), "aLang");}
}
// 输出结果
/*
class java.util.LinkedHashMap
name:aLang
age:27
skillList:[java, c++]
*/

4.5 Jackson 忽略字段

  如果在进行 JSON 转 Java 对象时,JSON 中出现了 Java 类中不存在的属性,那么在转换时会遇到 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException 异常。使用 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 可以忽略不存在的属性。

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.io.IOException;public class PersonTest04 {ObjectMapper objectMapper = new ObjectMapper();@Testpublic void jsonStringToPojo() throws IOException {String json = "{\"yyy\":\"xxx\",\"name\":\"aLang\",\"age\":27,\"skillList\":[\"java\",\"c++\"]}";objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);Person person = objectMapper.readValue(json, Person.class);System.out.printf(person.toString());Assertions.assertEquals(person.getName(), "aLang");Assertions.assertEquals(person.getSkillList().toString(), "[java, c++]");}
}
//输出结果
// Person(name=aLang, age=27, skillList=[java, c++])

4.6 Jackson 日期格式化

  在 Java 8 之前我们通常使用 java.util.Date 类来处理时间,但是在 Java 8 发布时引入了新的时间类 java.time.LocalDateTime. 这两者在 Jackson 中的处理略有不同。

// 创建订单Order对象
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.util.Date;@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {private Integer id;private Date createTime;private LocalDateTime updateTime;
}
4.6.1 Date类型的序列化与反序列化
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;import java.util.Date;public class DateTransform {ObjectMapper objectMapper = new ObjectMapper();@Testpublic void dateInPojoToJson() throws JsonProcessingException {Order order = new Order(1, new Date(), null);// 序列化为jsonString json = objectMapper.writeValueAsString(order);System.out.println(json);//反序列化为Order对象  order = objectMapper.readValue(json, Order.class);System.out.println(order.toString());Assertions.assertEquals(order.getId(), 1);}
}
/* 输出结果:
{"id":1,"createTime":1712729115179,"updateTime":null}
Order(id=1, createTime=Wed Apr 10 14:05:15 CST 2024, updateTime=null)
*/

可以看到正常的进行了 JSON 的序列化与反序列化,但是 JSON 中的时间是一个时间戳格式,可能不是我们想要的。

4.6.2 LocalDateTime类型的序列化与反序列化
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;import java.time.LocalDateTime;
import java.util.Date;public class OrderTest {ObjectMapper objectMapper = new ObjectMapper();@Testpublic void testPojoToJson() throws JsonProcessingException {Order order = new Order(1, new Date(), LocalDateTime.now());String json = objectMapper.writeValueAsString(order);System.out.println(json);order = objectMapper.readValue(json, Order.class);System.out.println(order.toString());Assertions.assertEquals(order.getId(), 1);}
}

运行报错:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type java.time.LocalDateTime not supported by default: add Module “com.fasterxml.jackson.datatype:jackson-datatype-jsr310” to enable handling (through reference chain: com.study.jackson.Order[“updateTime”])

添加对应的依赖:

<dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId><version>2.13.3</version>
</dependency>

添加依赖后的代码为:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;import java.time.LocalDateTime;
import java.util.Date;public class OrderTest {// 通过findAndRegisterModules注册依赖ObjectMapper objectMapper = new ObjectMapper().findAndRegisterModules();@Testpublic void testPojoToJson() throws JsonProcessingException {Order order = new Order(1, new Date(), LocalDateTime.now());String json = objectMapper.writeValueAsString(order);System.out.println(json);order = objectMapper.readValue(json, Order.class);System.out.println(order.toString());Assertions.assertEquals(order.getId(), 1);}
}
/* 输出结果:
{"id":1,"createTime":1712729605162,"updateTime":[2024,4,10,14,13,25,166000000]}
Order(id=1, createTime=Wed Apr 10 14:13:25 CST 2024, updateTime=2024-04-10T14:13:25.166)
*/
4.6.3 时间格式化

通过在字段上使用注解 @JsonFormat 来自定义时间格式。

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDateTime;
import java.util.Date;@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order1 {private Integer id;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")private Date createTime;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")private LocalDateTime updateTime;
}
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;import java.time.LocalDateTime;
import java.util.Date;public class OrderTest01 {ObjectMapper objectMapper = new ObjectMapper().findAndRegisterModules();@Testpublic void testPojoToJson() throws JsonProcessingException {Order1 order = new Order1(1, new Date(), LocalDateTime.now());String json = objectMapper.writeValueAsString(order);System.out.println(json);order = objectMapper.readValue(json, Order1.class);System.out.println(order);Assertions.assertEquals(order.getId(),1);}
}
/*
输出结果:
{"id":1,"createTime":"2024-04-10 14:22:17","updateTime":"2024-04-10 14:22:17"}
Order1(id=1, createTime=Wed Apr 10 14:22:17 CST 2024, updateTime=2024-04-10T14:22:17)
*/

5.总结

  • Jackson 是 Java 中比较流量的 JSON 处理库之一,它是 Spring 的默认 JSON 工具。
  • Jackson 主要有三个模块组成,Streaming API 、Annotations 和 Data Binding 。
  • Jackson 中的 ObjectMapper 类十分强大,可以进行 JSON 相关处理,同时可以结合注释以及配置进行自定义转换逻辑。
  • Jackson 扩展性很好,如 CSV、XML、YAML 格式处理都对 Jackson 有相应的适配等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/807149.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【实战JVM】类的生命周期

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

百度OCR身份证识别C++离线SDKV3.0 C#对接

百度OCR身份证识别C离线SDKV3.0 C#对接 目录 说明 效果 问题 项目 代码 下载 说明 自己根据SDK封装了动态库&#xff0c;然后C#调用。 SDK 简介 本 SDK 适应于于 Windows 平台下的⾝份证识别系统,⽀持 C接⼜开发的 SDK,开发者可在VS2015 下⾯进⾏开发&#xff08;推荐…

【Java基础题型】遍历1000以内的完数

一个数如果恰好等于不包含它本身所有因子之和&#xff0c;这个数就称为"完数"。 例如&#xff0c;6的因子为1、2、3&#xff0c;而6123&#xff0c;因此6是"完数"。 编程序找出N之内的所有完数&#xff0c;并按下面格式输出其因子 输入格式 N 输出格式( …

研究下福克斯的油耗

1.分析 09款1.8MT福克斯的真实油耗 https://zhidao.baidu.com/question/107309076 发改委的是匀速油耗 如果单纯是在市区行驶&#xff0c;还要看路况&#xff0c;经常塞车&#xff0c;红绿灯多等等&#xff0c;这样油耗就高了&#xff0c;一百公里起码10-11升 如果是在高速行…

推荐学习什么编程语言?

选择编程语言学习时&#xff0c;除了就业因素外&#xff0c;还可以考虑以下几个方面来决定学习哪些编程语言&#xff1a; 个人兴趣与目标&#xff1a;如果你对某个特定领域感兴趣&#xff0c;比如游戏开发、数据分析、人工智能等&#xff0c;可以选择与该领域紧密相关的编程语言…

Altair® Access™ 面向研究人员和工程师的 HPC 作业提交门户

Altair Access™ 面向研究人员和工程师的 HPC 作业提交门户 Access 具有一个简单、强大且统一的界面&#xff0c;可以从中提交和监控远程集群、云或其他资源的相关作业&#xff0c;使工程师和研究人员能够专注于主要活动&#xff0c;减少在应用程序运行及数据移动上投入的时间。…

搭建第一个Web服务器(在eclipse或idea上部署Tomcat服务器)

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

二维数组得学习

二维数组可以看作是一维数组的扩展&#xff0c;其元素本身又是一维数组。具体来说&#xff0c;一个m行n列的二维数组&#xff0c;既可以视为由m个一维数组&#xff08;行&#xff09;所组成的线性表&#xff0c;也可以视为由n个一维数组&#xff08;列&#xff09;所组成的线性…

算法练习第五十天|123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV

123. 买卖股票的最佳时机 III 188. 买卖股票的最佳时机 IV 123.买卖股票的最佳时机III class Solution {public int maxProfit(int[] prices) {//dp[i][j] 第i天买卖股票获得的最大利润/**j0不操作j1第一次持有j2第一次不持有j3第二次持有j4第二次不持有dp[i][0] dp[i-1][0]d…

518. 零钱兑换 II(力扣LeetCode)

文章目录 518. 零钱兑换 II题目描述动态规划一维数组为什么不能交换两个for循环的顺序&#xff1f; 二维数组 518. 零钱兑换 II 题目描述 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数…

2024年ERP软件上中下游结构分析及细分行业研究

环洋咨询Global Info Research的ERP软件市场调研报告提供ERP软件市场的基本概况&#xff0c;包括定义&#xff0c;分类&#xff0c;应用和产业链结构&#xff0c;同时还讨论发展政策和计划以及制造流程和成本结构&#xff0c;分析ERP软件市场的发展现状与未来市场趋势&#xff…

nandgame中的条件判断EQ(== 相等)、GT、LT、NOT、GOTO、IF_GOTO

相等从堆栈中弹出两个顶部值并进行比较。 如果它们相等&#xff0c;则推送值-1&#xff08;十六进制中的FFFF&#xff09;。 否则推送0。在条件语句中&#xff0c;FFFF代表真&#xff0c;0代表假。示例 之前 之后 堆栈 堆栈 7 0 8 结果如下&#xff1a; 代码 POP_D POP_A…

AI大模型探索之路-应用篇8:Langchain框架LangServe模块-专注于AI模型的部署

目录 前言 一、概述 二、功能特性 三、REST API 开发 四、Postman调用测试 五、Client调用测试 总结 前言 随着AI大语言模型&#xff08;LLM&#xff09;的技术的不断演进&#xff0c;AI应用的开发和部署变得越来越复杂。在这样的背景下&#xff0c;LangServe应运而生—…

设计模式——2_7 状态(State)

欲买桂花同载酒&#xff0c;终不似&#xff0c;少年游 ——刘过《唐多令芦叶满汀州》 文章目录 定义图纸一个例子&#xff1a;如何模拟一个转笔刀自动转笔刀PencilPencilSharpener 投诉和改善钝刀BladePencilSharpener 没有铅笔PencilSharpener if if ifStatePencilSharpener 碎…

python 读取文件内容每一行,写入另一个文件内

场景 想要利用 python 读取指定文件的中的内容&#xff0c;格式自行解析&#xff0c;然后将读取到的内容整理后再写入另一个文件中 步骤 读取文件将读取出来的每一行内容自定义修改一下将修改后的内容写入到另一个文件中 本地测试代码 # 打开源文件并读取其内容 with open…

48-基于腾讯云EKS的容器化部署实战

准备工作 在部署IAM应用之前&#xff0c;我们需要做以下准备工作&#xff1a; 开通腾讯云容器服务镜像仓库。安装并配置Docker。准备一个Kubernetes集群。 开通腾讯云容器服务镜像仓库 在Kubernetes集群中部署IAM应用&#xff0c;需要从镜像仓库下载指定的IAM镜像&#xff…

亚马逊、速卖通、lazada测评自养号与机刷有何区别?

在亚马逊平台&#xff0c;买家评价的重要性无需多言。许多消费者在决定购买产品前&#xff0c;都会习惯性地查看相关评论&#xff0c;对比同类产品的买家反馈&#xff0c;从而做出更明智的选择。正因如此&#xff0c;测评成为各大电商平台不可或缺的一种推广策略&#xff0c;亚…

蓝桥杯备考day3

1.1 DFS模板&#xff08;深度优先遍历&#xff09; 模板 全局状态变量 void dfs(当前状态) {if(当前状态是目标状态) // 判断进行相应处理&#xff08;输出当前解、更新最优解、退出返回等&#xff09;// 扩展for(所有可行的新状态){if(新状态没有访问过 && 需要访问…

C++ 模拟实现 STL 中的 set、map 与 multiset、multimap

目录 一&#xff0c;RB_tree 的实现 1&#xff0c;RB_tree 的节点与数据结构 2&#xff0c;RB_tree 的迭代器 3&#xff0c;RB_tree 的构造 4&#xff0c;RB_tree 的元素操作 5&#xff0c;完整代码 二&#xff0c;set 与 multiset 的实现 1&#xff0c;set 2&#x…

从零开始:Elasticsearch简介与详解

大家好,我是小米,今天我来和大家聊一聊阿里巴巴面试题中常见的一个话题:Elasticsearch。作为一名喜欢分享技术的小伙伴,我深知在技术的道路上,多一份了解就多一份优势。那么,让我们一起来探索一下Elasticsearch的特点、功能、场景以及与竞品的对比分析吧! 特点 特点是…