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;推荐…

推荐学习什么编程语言?

选择编程语言学习时&#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…

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 碎…

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

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

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

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

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的特点、功能、场景以及与竞品的对比分析吧! 特点 特点是…

js爬虫puppeteer库 解决网页动态渲染无法爬取

我们爬取这个网址上面的股票实时部分宇通客车(600066)_股票价格_行情_走势图—东方财富网 我们用正常的方法爬取会发现爬取不下来&#xff0c;是因为这个网页这里是实时渲染的&#xff0c;我们直接通过网址接口访问这里还没有渲染出来 于是我们可以通过下面的代码来进行爬取: …

1. VirtualBox安装CentOS

安装 VirtualBox 地址:https://www.virtualbox.org/wiki/Downloads 版本: 6.1和7.0+版本都可以 安装: windows上安装需要admin权限,右键菜单选中 “Run as administrator” 安装 CentOS 6.10 地址:https://vault.centos.org/6.10/isos/x86_64/ 版本: 如果不需要GUI,选择…

混合云构建-如何通过Site to Site VPN 连接 AWS 和GCP云并建立一个高可用的VPN通信

如果我们的业务环境既有AWS云又有GCP云,那么就需要将他们打通,最经济便捷的方式就是通过Site-to-Site VPN连接AWS和GCP云,你需要在两个云平台上分别配置VPN网关,并建立一个VPN隧道来安全地连接这两个环境,我们下面演示一个高可用场景下的S2S VPN线路构建,采用动态BGP协议…

利用dbschema工具导出数据库结构

dbschema是SinoDB数据库的一个命令行工具&#xff0c;可以用来导出SinoDB数据库的所有对象&#xff08;如表、触发器、视图等&#xff09;的元数据。以下是常见的使用方法&#xff1a; 1、导出数据库中所有的表结构到文件db.sql $dbschema -d your_database_name -t all db.sq…

岛屿个数c++

参考文章 岛屿个数1岛屿个数2 题目 输入样例&#xff1a; 2 5 5 01111 11001 10101 10001 11111 5 6 111111 100001 010101 100001 111111输出样例&#xff1a; 1 3样例解释 对于第一组数据&#xff0c;包含两个岛屿&#xff0c;下面用不同的数字进行了区分&#xff1a; 0…

Torch not compiled with CUDA enabled问题解决过程记录

1. 背景 运行大模型的时候&#xff0c;出现错误:Torch not compiled with CUDA enabled 原因&#xff1a;并不是电脑安装了nvdia显卡驱动就可以的&#xff0c;还需要安装 NVDIA GPU Computing Toolkit&#xff08;即CUDA Toolkit&#xff09;cudnn 另外还需要确保安装的pyt…

ROS2 采集虚拟仿真环境图像并发布

简介&#xff1a;ROS2功能的学习我们还是在基于OpenAI的gym虚拟仿真环境中来完成&#xff0c;gym虚拟仿真环境安装请参考另一篇教程&#xff0c;这里不再重复说明&#xff0c;接下来我们开始创建一个ROS2的功能节点&#xff0c;并发布虚拟仿真环境小车摄像头的图像&#xff0c;…