Json 全称是 JavaScript Object Notation,是一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。它易于阅读和编写,同时也易于计算机解析和生成,并能够有效的提升网络传输效率,简洁清晰的层次结构,使得 JSON 成为目前主流的数据交换语言。
本篇博客主要介绍 Java 使用第三方 Jackson 的 jar 包,实现 Java Bean 对象与 Json 字符串之间的数据转换,以及在不使用 Java Bean 对象作为转换目标的情况下,读取 Json 字段获取数据的实现方式。在博客的末尾会提供源代码。
Jackson 的官网地址:https://github.com/codehaus/jackson
一、搭建示例工程
新建一个 maven 工程,并导入 Jackson 的 jar 包。
Jackson 的 jar 包一共有 3 个,分别为:
jackson-core:这个最底层核心 jar 包,提供基于”流模式”解析的相关 API,其 jar 包地址为:
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
jackson-annotations:这个是注解包,提供标准注解功能,其 jar 包地址为:
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
jackson-databind:这个数据绑定包, 提供基于【对象绑定】解析的相关 API和【树模型”】解析的相关 API,其 jar 包地址:
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
由于 jackson-databind 依赖 jackson-core 和 jackson-annotations,当我们使用 maven 导入 jackson-databind 的 jar 包引用之后, jackson-core 和 jackson-annotations 这 2 个 jar 包也会自动添加到 maven 项目工程中。
因此我们只需要导入 jackson-databind 的 jar 包即可。我导入的是最新的 jackson-databind 的 jar 包,另外为了方便测试,也导入了最新的 juint 的 jar 包,具体内容如下:
<!--导入 jackson-databind 的 jar 包-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.1</version>
</dependency>
<!--导入 junit 的 jar 包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
配置好引用的 jar 包后,打开右侧的 Maven 窗口,刷新一下,这样 Maven 会自动下载所需的 jar 包文件。
搭建好的项目工程整体目录比较简单,具体如下图所示:
项目工程结构简单介绍:
com.jobs.bean.employee 员工实体类
test 目录下的文件介绍:
com.jobs.jsonTest 类是专门用来编写 junit 单元测试方法,用来测试所编写的 json 处理方法
resources 下的 data.json 文件中存储一段 json 数据,用于在本 demo 中进行解析
二、细节展示
com.jobs.bean.employee 员工实体类的内容如下:
package com.jobs.bean;
import java.util.Objects;
public class employee {
private String name; //姓名
private Integer age; //年龄
public employee() {
}
public employee(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
//重写 equals 和 hashCode 方法,用于 employee 对象的去重:
//当两个 employee 对象的 name 和 age 属性值一样的话,认为是相同的 employee 对象
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
employee employee = (employee) o;
return Objects.equals(name, employee.name) && Objects.equals(age, employee.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
//重新 toString() 方法,用于打印出 employee 对象的细节,方便查看
@Override
public String toString() {
return "employee{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
test 下面 resources 目录下的 data.json 内容如下:
{
"status": 0,
"msg": "成功",
"data": {
"address": {
"street": "黄金屋",
"city": "科技复兴",
"province": "地球"
},
"friends": [
"侯胖胖",
"任肥肥",
"蔺赞赞",
"李敦敦",
"杨帅帅"
]
}
}
com.jobs.jsonTest 类是编写处理 json 数据的测试类,具体内容如下:
package com.jobs;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jobs.bean.employee;
import org.junit.Test;
import java.io.*;
import java.util.*;
public class jsonTest {
//创建对象绑定模型对象 ObjectMapper 对象的实例,方便下面的测试方法直接使用
private ObjectMapper mapper = new ObjectMapper();
//JavaBean 与 Json 之间的转换
@Test
public void test01() throws Exception {
//将 bean 对象转换为 json 字符串
employee emp = new employee("侯胖胖", 40);
String json = mapper.writeValueAsString(emp);
System.out.println(json);
//将字符串转换为 bean 对象
employee result = mapper.readValue(json, employee.class);
System.out.println(result);
}
//Java 自带的数据结构(里面是 Java 自带的数据类型)与 Json 之间的转换
@Test
public void test02() throws Exception {
List<String> list = new ArrayList<>();
list.add("候胖胖");
list.add("任肥肥");
list.add("李敦敦");
//将 List 转换为 json 字符串
String listJson = mapper.writeValueAsString(list);
System.out.println(listJson);
//将 json 转换为 List
List<String> listResult = mapper.readValue(listJson, List.class);
System.out.println(listResult);
System.out.println("---------------------------------");
Map<String, Integer> map = new HashMap<>();
map.put("侯胖胖", 40);
map.put("任肥肥", 38);
map.put("李敦敦", 26);
//将 Map 转换为 json 字符串
String mapJson = mapper.writeValueAsString(map);
System.out.println(mapJson);
//将 json 转换为 Map
Map<String, Integer> mapResult = mapper.readValue(mapJson, Map.class);
System.out.println(mapResult);
System.out.println("---------------------------------");
Set<String> set = new HashSet<>();
set.add("候胖胖");
set.add("任肥肥");
set.add("李敦敦");
set.add("任肥肥");
set.add("候胖胖");
//将 Set 转换为 json 字符串
String setJson = mapper.writeValueAsString(set);
System.out.println(setJson);
//将 json 转换为 Set
Set<String> setResult = mapper.readValue(setJson, Set.class);
System.out.println(setResult);
}
//Java 自带的数据结构(里面是自定义的 JavaBean 类对象)与 Json 之间的转换
//需要使用 TypeReference 来将进行 json 与自定义 JavaBean 类对象之间的对应
@Test
public void test03() throws Exception {
List<employee> list = new ArrayList<>();
list.add(new employee("侯胖胖", 40));
list.add(new employee("任肥肥", 38));
list.add(new employee("李敦敦", 26));
//将 List 转换为 json 字符串
String listJson = mapper.writeValueAsString(list);
System.out.println(listJson);
//将 json 转换为 List
List<employee> listResult =
mapper.readValue(listJson, new TypeReference<List<employee>>() {});
System.out.println(listResult);
System.out.println("---------------------------------");
Map<String, employee> map = new HashMap<>();
map.put("破坏之王", new employee("侯胖胖", 40));
map.put("埋坑专家", new employee("任肥肥", 38));
map.put("拆蛋大神", new employee("李敦敦", 26));
//将 Map 转换为 json 字符串
String mapJson = mapper.writeValueAsString(map);
System.out.println(mapJson);
//将 json 转换为 Map
Map<String, employee> mapResult =
mapper.readValue(mapJson, new TypeReference<Map<String, employee>>() {});
System.out.println(mapResult);
System.out.println("---------------------------------");
Set<employee> set = new HashSet<>();
set.add(new employee("侯胖胖", 40));
set.add(new employee("任肥肥", 38));
set.add(new employee("李敦敦", 26));
set.add(new employee("任肥肥", 38));
set.add(new employee("侯胖胖", 40));
//将 Set 转换为 json 字符串
String setJson = mapper.writeValueAsString(set);
System.out.println(setJson);
//将 json 转换为 Set
Set<employee> setResult =
mapper.readValue(setJson, new TypeReference<Set<employee>>() {});
System.out.println(setResult);
}
//不使用 JavaBean ,采用 JsonNode 读取 Json 字段的数据
@Test
public void test04() throws Exception {
//获取 data.json 的文件路径
String dataPath = jsonTest.class
.getClassLoader().getResource("data.json").getPath();
//从 data.json 文件中读取 json 数据
StringBuilder sb = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(dataPath))) {
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
}
System.out.println("-------------从文件中获取到的 json 数据:");
String json = sb.toString().replace(" ", "");
System.out.println(json); //把 data.json 文件中的 json 数据打印出来
System.out.println("-------------解析 json 数据:");
//json 具有树模型的特征,因此可以按照树形结构进行解析
JsonNode root = mapper.readTree(json);
//获取 int 类型的 status 值
int status = root.get("status").asInt();
System.out.println("status 为 " + status);
//获取 String 类型的 msg 值
String msg = root.get("msg").asText();
System.out.println("msg 为 " + msg);
//获取 address 数据
JsonNode address = root.get("data").get("address");
String street = address.get("street").asText();
String city = address.get("city").asText();
String province = address.get("province").asText();
System.out.println("address 数据如下:");
System.out.println("\t" + "province 为 " + province);
System.out.println("\t" + "city 为 " + city);
System.out.println("\t" + "street 为 " + street);
//获取 friends 数组数据
JsonNode friends = root.get("data").get("friends");
System.out.println("friends 数据如下:");
for (JsonNode item : friends) {
System.out.println("\t" + item.asText());
}
}
}
需要注意的一点就是:如果想把 json 转换为自定义的 JavaBean 对象,需要使用 TypeReference 。
上面代码中最后一个方法,模拟的实际场景是:当我们调用相关接口或从其它某种途径获取到 Json 数据时,不想创建与 Json 字段相对应的实体类时,可以采用 Json 树模型的方案来进行解析,获取相关 Json 字段的值。
本 demo 的源代码下载地址为:https://files.cnblogs.com/files/blogs/699532/jacksondemo.zip
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/191154.html