Json格式数据解析

article/2025/11/11 1:11:56

一、简介

XML这种数据格式。XML的特点是功能全面,但标签繁琐,格式复杂。在Web上使用XML现在越来越少,取而代之的是JSON这种数据结构。

JSON是JavaScript Object Notation的缩写,它去除了所有JavaScript执行代码,只保留JavaScript的对象格式。典型的JSON如下:

  1. json对象
    {
    ​"ID": 1001,
    ​"name": "张三",
    ​
    }
    /*
    特点:
    数据在花括号中数据以"键:值"对的形式出现(其中键多以字符串形式出现,值可取字符串,数值,甚至其他json对象)
    每两个"键:值"对以逗号分隔(最后一个"键:值"对省略逗号)
    */
  2. json对象数组
    {
    ​"部门名称":"研发部",
    ​"部门成员":[
    ​{"ID": 1001, "name": "张三", "age": 24},
    ​{"ID": 1002, "name": "李四", "age": 25},
    ​{"ID": 1003, "name": "王五", "age": 22}],
    ​"部门位置":"xx楼21号"
    ​
    }
  3. json字符串

    JSON字符串也是在平时开发中使用较多的,json字符串应满足以下条件:

    1:它必须是一个字符串,由" "或者' '包裹数据,支持字符串的各种操作

    2:里面的数据格式应该要满足其中一个格式,可以是json对象,也可以是json对象数组或者是两种基本形式的组合变形。

二、特点

JSON作为数据传输的格式,有几个显著的优点:

  • JSON只允许使用UTF-8编码,不存在编码问题;
  • JSON只允许使用双引号作为key,特殊字符用\转义,格式简单;
  • 浏览器内置JSON支持,如果把数据用JSON发送给浏览器,可以用JavaScript直接处理。

三、前端处理json数据

开发Web应用的时候,使用JSON作为数据传输,在浏览器端非常方便。因为JSON天生适合JavaScript处理,所以,绝大多数REST API都选择JSON作为数据传输格式

1.json字符串转成对象, 使用json.parse(jsonStr)

2.json格式对象转成json格式字符串,使用JSON.stringify(jsonObj);

var jsonObj = {"name":"张三","age":14};

使用JSON.stringify(jsonObj);

四、Java如何对JSON进行读写?

在Java中,针对JSON也有标准的JSR 353 API,但是我们在前面讲XML的时候发现,如果能直接在XML和JavaBean之间互相转换是最好的。类似的,如果能直接在JSON和JavaBean之间转换,那么用起来就简单多了。

常用的用于解析JSON的第三方库有:

  • Jackson
  • Gson
  • Fastjson

1、使用FastJson解析数据

1.1、语法

在fastjson包中主要有3个类,JSON,JSONArray,JSONObject

三者之间的关系如下,JSONObject和JSONArray继承JSON

JSONObject代表json对象,

JSONArray代表json对象数组,

JSON代表JSONObject和JSONArray的转化。

JSONObject类使用

JSONObject实现了Map接口,而json对象中的数据都是以"键:值"对形式出现, JSONObject底层操作是由Map实现的。类中主要是get()方法。JSONObject相当于json对象,该类中主要封装了各种get方法,通过"键:值"对中的键来获取其对应的值。

JSONArray类使用

JSONArray的内部是通过List接口中的方法来完成操作的。JSONArray代表json对象数组,json数组对象中存储的是一个个json对象,所以类中的方法主要用于直接操作json对象。比如其中的add(),remove(),containsAll()方法,对应于json对象的添加,删除与判断。 其内部主要由List接口中的对应方法来实现。

跟JSONObject一样,JSONArray里面也有一些get()方法,不过不常用,最有用的应该是getJSONObject(int index)方法,该方法用于获取json对象数组中指定位置的JSONObject对象,配合size()方法,可用于遍历json对象数组中的各个对象。 通过以上两个方法,在配合for循环,即可实现json对象数组的遍历。此外JSONArray中也实现了迭代器方法来遍历。 通过遍历得到JSONObject对象,然后再利用JSONObject类中的get()方法,即可实现最终json数据的获取。

JSON类使用

JSON类主要是实现转化用的,最后的数据获取,还是要通过JSONObject和JSONArray来实现。类中的主要是实现json对象,json对象数组,javabean对象,json字符串之间的相互转化。

1.2、使用

json字符串—》JSONObject

用JSON.parseObject()方法即可将JSon字符串转化为JSON对象,利用JSONObject中的get()方法来获取JSONObject中的相对应的键对应的值

//json格式数据---对象类型
String  JSON_OBJ_STR = "{\"studentName\":\"lily\",\"studentAge\":12}";
JSONObject jsonObject = JSON.parseObject(JSON_OBJ_STR);
System.out.println("StudentName: " + jsonObject.getString("studentName") + "," + "StudentAge: " + jsonObject.getInteger("studentAge"));

JSONObject—》json字符串

用JSON.toJSONString()方法即可将JSON对象转化为JSON字符串

JSON字符串数组—》JSONArray

将JSON字符串数组转化为JSONArray,通过JSON的parseArray()方法。JSONArray本质上还是一个数组,对其进行遍历取得其中的JSONObject,然后再利用JSONObject的get()方法取得其中的值。有两种方式进行遍历

方式一:通过jsonArray.size()获取JSONArray中元素的个数,再通过getJSONObject(index)获取相应位置的JSONObject,循环变量取得JSONArray中的JSONObject,再利用JSONObject的get()进行取值。

方式二:通过jsonArray.iterator()获取迭代器

JSON_ARRAY_STR = "     [{\"studentName\":\"lily\",\"studentAge\":12}," +"{\"studentName\":\"lucy\",\"studentAge\":15}]";
JSONArray jsonArray = JSON.parseArray(JSON_ARRAY_STR);
// 遍历方式一
//        int size = jsonArray.size();
//        for(int i = 0;i < size;i++){
//            JSONObject jsonObject = jsonArray.getJSONObject(i);
//            System.out.println("studentName: " + jsonObject.getString("studentName") + ",StudentAge: " + jsonObject.getInteger("studentAge"));
//        }
// 遍历方式二Iterator<Object> iterator = jsonArray.iterator();while (iterator.hasNext()){JSONObject jsonObject = (JSONObject) iterator.next();System.out.println("studentName: " + jsonObject.getString("studentName") + ",StudentAge: " + jsonObject.getInteger("studentAge"));}

JSONArray—》json字符串

用JSON.toJSONString()方法即可将JSONArray转化为JSON字符串

json字符串—》JavaBean

String  JSON_OBJ_STR = "{\"studentName\":\"lily\",\"studentAge\":12}";
// 第一种方式JSONObject jsonObject = JSON.parseObject(JSON_OBJ_STR);String studentName = jsonObject.getString("studentName");Integer studentAge = jsonObject.getInteger("studentAge");Student student = new Student(studentName, studentAge);
// 第二种方式,//第二种方式,使用TypeReference<T>类,由于其构造方法使用protected进行修饰,故创建其子类Student student1 = JSON.parseObject(JSON_OBJ_STR, new TypeReference<Student>() {});
// 第三种方式,通过反射,建议这种方式Student student2 = JSON.parseObject(JSON_OBJ_STR, Student.class);

JavaBean —》json字符串

也是通过JSON的toJSONString,不管是JSONObject、JSONArray还是JavaBean转为为JSON字符串都是通过JSON的toJSONString方法。

Student lily = new Student("lily", 12);
String s = JSON.toJSONString(lily);

json字符串数组—》JavaBean-List

JSON_ARRAY_STR = "     [{\"studentName\":\"lily\",\"studentAge\":12}," +"{\"studentName\":\"lucy\",\"studentAge\":15}]";
// 方式一:JSONArray jsonArray = JSON.parseArray(JSON_ARRAY_STR);//遍历JSONArrayList<Student> students = new ArrayList<Student>();Iterator<Object> iterator = jsonArray.iterator();while (iterator.hasNext()){JSONObject next = (JSONObject) iterator.next();String studentName = next.getString("studentName");Integer studentAge = next.getInteger("studentAge");Student student = new Student(studentName, studentAge);students.add(student);}// 方式二,使用TypeReference<T>类,由于其构造方法使用protected进行修饰,故创建其子类List<Student> studentList = JSON.parseObject(JSON_ARRAY_STR,new TypeReference<ArrayList<Student>>() {});// 方式三,使用反射List<Student> students1 = JSON.parseArray(JSON_ARRAY_STR, Student.class);System.out.println(students1);

 JavaBean-List —》json字符串数组

JavaBean_List到json字符串-数组类型的转换,直接调用JSON.toJSONString()方法即可

复杂嵌套json格式字符串—》JavaBean_obj

对于复杂嵌套的JSON格式,利用JavaBean进行转换的时候要注意:

有几个JSONObject就定义几个JavaBean

内层的JSONObject对应的JavaBean作为外层JSONObject对应的JavaBean的一个属性

public class Student {private String studentName;private int studentAge;
​public Student() {}
​public Student(String studentName, int studentAge) {this.studentName = studentName;this.studentAge = studentAge;}
​public String getStudentName() {return studentName;}
​public void setStudentName(String studentName) {this.studentName = studentName;}
​public int getStudentAge() {return studentAge;}
​public void setStudentAge(int studentAge) {this.studentAge = studentAge;}
​@Overridepublic String toString() {return "Student{" +"studentName='" + studentName + '\'' +", studentAge=" + studentAge +'}';}
}
​​
import java.util.List;
​
public class Teacher {private String teacherName;private int teacherAge;private Course course;private List<Student> students;
​public Teacher() {}
​public Teacher(String teacherName, int teacherAge, Course course, List<Student> students) {this.teacherName = teacherName;this.teacherAge = teacherAge;this.course = course;this.students = students;}
​public String getTeacherName() {return teacherName;}
​public void setTeacherName(String teacherName) {this.teacherName = teacherName;}
​public int getTeacherAge() {return teacherAge;}
​public void setTeacherAge(int teacherAge) {this.teacherAge = teacherAge;}
​public Course getCourse() {return course;}
​public void setCourse(Course course) {this.course = course;}
​public List<Student> getStudents() {return students;}
​public void setStudents(List<Student> students) {this.students = students;}
​@Overridepublic String toString() {return "Teacher{" +"teacherName='" + teacherName + '\'' +", teacherAge=" + teacherAge +", course=" + course +", students=" + students +'}';}
}​
public class Course {private String courseName;private int code;
​public Course() {}
​public Course(String courseName, int code) {this.courseName = courseName;this.code = code;}
​public String getCourseName() {return courseName;}
​public void setCourseName(String courseName) {this.courseName = courseName;}
​public int getCode() {return code;}
​public void setCode(int code) {this.code = code;}
​@Overridepublic String toString() {return "Course{" +"courseName='" + courseName + '\'' +", code=" + code +'}';}
}//第一种方式,使用TypeReference<T>类,由于其构造方法使用protected进行修饰,故创建其子类Teacher teacher = JSON.parseObject(COMPLEX_JSON_STR, new TypeReference<Teacher>() {});
// 第二种方式,使用反射Teacher teacher1 = JSON.parseObject(COMPLEX_JSON_STR, Teacher.class);

JavaBean_obj —》复杂json格式字符串

Teacher teacher = JSON.parseObject(COMPLEX_JSON_STR, Teacher.class);String s = JSON.toJSONString(teacher);

备注:设置实体中的某个属性转json

2、使用JackJson解析数据

2.1、简介

Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架。

Jackson 社区相对比较活跃,更新速度也比较快, 从 Github 中的统计来看,Jackson 是最流行的 json 解析器之一 。

Spring MVC 的默认 json 解析器便是 Jackson。

Jackson 优点很多。 Jackson 所依赖的 jar 包较少 ,简单易用。

与其他 Java 的 json 的框架 Gson 等相比, Jackson 解析大的 json 文件速度比较快

Jackson 运行时占用内存比较低,性能比较好

Jackson 有灵活的 API,可以很容易进行扩展和定制。

Jackson 的 1.x 版本的包名是 org.codehaus.jackson ,当升级到 2.x 版本时,包名变为 com.fasterxml.jackson。

Jackson可以解析JSON也可以解析xml

Jackson 的核心模块由三部分组成。

jackson-core,核心包,提供基于"流模式"解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。
jackson-annotations,注解包,提供标准注解功能;
jackson-databind ,数据绑定包, 提供基于"对象绑定" 解析的相关 API ( ObjectMapper ) 和"树模型" 解析的相关 API (JsonNode);基于"对象绑定" 解析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API。
源码地址:https://github.com/FasterXML/jackson
当然了,jackson-databind 依赖 jackson-core 和 jackson-annotations,所以可以只显示地添加jackson-databind依赖,jackson-core 和 jackson-annotations 也随之添加到 Java 项目工程中。

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.6</version>
</dependency>

2.3、使用

使用下面的代码解析一个JSON文件:

InputStream input = Main.class.getResourceAsStream("/book.json");
ObjectMapper mapper = new ObjectMapper();
// 反序列化时忽略不存在的JavaBean属性:
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Book book = mapper.readValue(input, Book.class);

核心代码是创建一个ObjectMapper对象。关闭DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES功能使得解析时如果JavaBean不存在该属性时解析不会报错。

把JSON解析为JavaBean的过程称为反序列化。如果把JavaBean变为JSON,那就是序列化。要实现JavaBean到JSON的序列化,只需要一行代码:

String json = mapper.writeValueAsString(book);

要把JSON的某些值解析为特定的Java对象,例如LocalDate,也是完全可以的。例如:

{"name": "Java核心技术","pubDate": "2016-09-01"
}

要解析为:

public class Book {public String name;public LocalDate pubDate;
}

只需要引入标准的JSR 310关于JavaTime的数据格式定义至Maven:

  • com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.0

然后,在创建ObjectMapper时,注册一个新的JavaTimeModule

ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());

有些时候,内置的解析规则和扩展的解析规则如果都不满足我们的需求,还可以自定义解析。

举个例子,假设Book类的isbn是一个BigInteger

public class Book {public String name;public BigInteger isbn;
}

但JSON数据并不是标准的整形格式:

{"name": "Java核心技术","isbn": "978-7-111-54742-6"
}

直接解析,肯定报错。这时,我们需要自定义一个IsbnDeserializer,用于解析含有非数字的字符串:

public class IsbnDeserializer extends JsonDeserializer<BigInteger> {public BigInteger deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {// 读取原始的JSON字符串内容:String s = p.getValueAsString();if (s != null) {try {return new BigInteger(s.replace("-", ""));} catch (NumberFormatException e) {throw new JsonParseException(p, s, e);}}return null;}
}

然后,在Book类中使用注解标注:

public class Book {public String name;// 表示反序列化isbn时使用自定义的IsbnDeserializer:@JsonDeserialize(using = IsbnDeserializer.class)public BigInteger isbn;
}

类似的,自定义序列化时我们需要自定义一个IsbnSerializer,然后在Book类中标注@JsonSerialize(using = ...)即可。

反序列化

在反序列化时,Jackson要求Java类需要一个默认的无参数构造方法,否则,无法直接实例化此类。存在带参数构造方法的类,如果要反序列化,注意再提供一个无参数构造方法。

对于enum字段,Jackson按String类型处理,即:

class Book {public DayOfWeek start = MONDAY;
}

序列化为:

{"start": "MONDAY"
}

对于record类型,Jackson会自动找出它的带参数构造方法,并根据JSON的key进行匹配,可直接反序列化。对record类型的支持需要版本2.12.0以上。

使用详解参考

Jackson使用详解_wh柒八九的博客-CSDN博客_jackson使用


http://chatgpt.dhexx.cn/article/VbblLVRa.shtml

相关文章

JSON解析

#粤嵌星计划&#xff0c;粤嵌我来了# #粤嵌星计划&#xff0c;粤嵌我来了# 1、什么是JSON &#xff08;1&#xff09;JSON&#xff08;Java Script Object Notation&#xff09;是一种轻量级的数据交换语言&#xff0c;以文本字符串为基础&#xff0c;且易于让人阅读。&#x…

内网穿透原理解析

在互联网信息时代的今天&#xff0c;经常会听到外网连接。而与外网所相对应的&#xff0c;是一种内部网络&#xff0c;很多的家庭或者公司利用内部网络来进行多台电脑之间的资源共享&#xff0c;其中所用到的技术就是内网穿透技术&#xff0c;但却有很多的人对这种技术并不了解…

内网穿透原理概要

详细原理的解析 https://blog.csdn.net/xinpz/article/details/82732217 运行原理流程图 什么是内网穿透? 内网穿透是我们在进行网络连接时的一种术语&#xff0c;也叫做NAT穿透&#xff0c;即在计算机是局域网内的时候&#xff0c;外网与内网的计算机的节点进行连接时所需…

内网穿透内容讲解

内网穿透又叫端口映射&#xff0c;用一句最简单的话来讲就是&#xff1a;将你的计算机所连接的私有网络映射到公网上&#xff0c;别人通过你给的域名或ip即可访问你本地的服务。具体的原理可参照百度百科 这么做可以实现各大厂商的云服务器&#xff08;阿里云&#xff0c;腾讯云…

内网穿透你真的了解吗?

前言 内网穿透作为程序员常用的调试手段之一&#xff0c;我们可以通过在个人电脑上运行花生壳或者 frp 等方式&#xff0c;让他人访问我们本地启动的服务&#xff0c;而且这种访问可以不受局域网的限制&#xff0c;当我们使用ngrok,frp等开源框架时&#xff0c;你是否有好奇过…

Ngrok内网穿透

Ngrok一款内网穿透工具&#xff0c;它可以将本地部署的Web应用能够让公网环境直接访问到。ngrok是一个反向代理&#xff0c;通过在公共端点和本地运行的Web服务器之间建立一个安全的通道&#xff0c;实现内网主机的服务可以暴露给外网。所以它提供了一个能够在公网安全访问内网…

大白话告诉你内网穿透原理和验证

内网穿透到底干啥的这里不做详述&#xff0c;这篇文章主要是讲这玩意怎么做的 分析 网上有很多原理图&#xff0c;但是说实话鄙人天资愚钝没咋看懂&#xff0c;在网上疯狂百度和个人的验证之后&#xff0c;得出如下简图 其实很简单 想让我们内网的服务能被外网访问到&#x…

frp内网穿透原理及配置应用

1 Frp介绍 frp 是一个专注于内网穿透的高性能的反向代理应用&#xff0c;支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。 frp 项目官网 https://github.com/fatedier/frp 中文文档 https://github.com/fat…

内网穿透原理,以及用花生壳实现内网穿透

在做自学项目部署nginx的时候&#xff0c;nginx部署在阿里云服务器上&#xff0c;项目在本地&#xff0c;阿里云的nginx无法访问到本地的ip&#xff0c;所以需要做一下内网穿透。记录一下 什么是内网穿透&#xff1f; 内网和外网的概念&#xff1a; 内网&#xff1a;即所说的局…

内网穿透原理和实现

什么是内网穿透 作者&#xff1a;匿名用户 链接&#xff1a;https://www.zhihu.com/question/63098230/answer/1929852198 希望对你们更易懂要知道这个的意思&#xff0c;需要先来点前菜 1、地球上的电脑设备等要实现通信&#xff0c;都需要有个IP地址才可以实现。 2、IP地址…

内网穿透原理和实现思路介绍

内网穿透技术&#xff0c;简单理解就是将内网的服务映射到公网中&#xff0c;这样可以随时随地访问。 那什么是内网&#xff1f;什么是公网&#xff1f;先从这个基本概念来简单介绍吧 1. 公网、内网和外网 首先声明&#xff0c;公网、内网和外网这几个概念&#xff0c;不是专…

内网穿透工具frp原理和使用教程

内网穿透&#xff08;Port Forwarding&#xff09;是将公网上的IP地址映射到内部网络中的一台计算机的某个端口上&#xff0c;以便外部网络可以访问该计算机中运行的应用程序。内网穿透技术可以通过一些开源工具来实现&#xff0c;其中比较常用的是frp。在本文中&#xff0c;我…

内网穿透原理

前言 内网穿透一般在家庭用户下NAS设备在经常折腾&#xff0c;实际上企业云服务就是典型的内网穿透&#xff0c;只不过方式原理有点不同&#xff0c;家庭网络因为宽带的上传限制和没有公网IP&#xff0c;难度大于企业宽带。实际上内网穿透就是反向代理&#xff0c;域名解析&am…

内网穿透的实现和原理解析

需求场景: 基于微信平台开发服务号&#xff0c;本地移动端测试时&#xff0c;需要在微信平台注册测试号&#xff0c;然后填写接口配置信息&#xff0c;此信息需要你有自己的服务器资源&#xff0c;填写的URL需要正确响应微信发送的Token验证。如何能让外网访问到本地服务器呢&…

MacBook M1 Idea集成SVN

1.检查是否安装SVN svn —version2.检查是否安装了brew brew -v3.安装 brew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)” speed4.记住安装路径 5.配置国内镜像源HOMEBREW BOTTLE 6.svn安装前需要执行 按照/usr/local路径…

IntelliJ IDEA上svn分支管理和使用

IntelliJ IDEA上svn分支管理和使用 从Subversion下载trunk下的代码 选择项目创建分支 右键 Subversion --> branch or Tag … 选择Repository Location:需要创建的项目 选择Any Location 分支的位置和名字 详细查看截图 切换到分支 选择项目右键Subversion --> Update …

vscode / idea 使用SVN及查看历史记录

一、vscode使用 SVN 1、在vscode插件中心搜索svn 进行安装&#xff08;我这里已经安装完毕了&#xff09; 注意&#xff1a;插件安装成功&#xff0c;需要重新启动软件。 安装成功后会出现如下的图标&#xff1a; 2、桌面右键使用SVN Checkout… 来检出远程库的代码&#xf…

IDEA之配置SVN

最近在公司的开发项目过程中&#xff0c;发现有关idea2020的svn配置方法都参差不齐&#xff0c;所以整理了有关idea2020整合svn的步骤&#xff1b; 目录 一、SVN配置1.1 下载SVN1.2 安装SVN1.3 配置SVN 二、常见问题2.1 Warning:java: 源值1.5已过时 一、SVN配置 1.1 下载SVN…

IDEA使用svn拉取多模块项目

如果没有安装过svn客户端,安装的时候需要选择安装第二个工具,如下图所示 安装小乌龟, 自行搜索, 注意点是需要选择安装第二个工具 因为默认是不安装的, 而这个组件是集成到IDEA ”必须的” . 如果是已经安装好的, 但是没有选这个的也是有办法的 办法一: 更改小乌龟 在卸载小乌龟…

idea 使用svn出现path to certificate

百度了一会&#xff0c;有说清缓存的&#xff0c;不能使用。 还有配置这个的&#xff0c;也不行。 我记得以前可以&#xff0c;后来发现你拉去代码不用在idea拉&#xff0c;能提交。只要你不选最外层项目。可能是我打开了两个idea&#xff0c;都用的这个链接&#xff0c;只是文…