Json格式数据解析
一、简介
XML这种数据格式。XML的特点是功能全面,但标签繁琐,格式复杂。在Web上使用XML现在越来越少,取而代之的是JSON这种数据结构。
JSON是JavaScript Object Notation的缩写,它去除了所有JavaScript执行代码,只保留JavaScript的对象格式。典型的JSON如下:
- json对象
{ "ID": 1001, "name": "张三", } /* 特点: 数据在花括号中数据以"键:值"对的形式出现(其中键多以字符串形式出现,值可取字符串,数值,甚至其他json对象) 每两个"键:值"对以逗号分隔(最后一个"键:值"对省略逗号) */
- json对象数组
{ "部门名称":"研发部", "部门成员":[ {"ID": 1001, "name": "张三", "age": 24}, {"ID": 1002, "name": "李四", "age": 25}, {"ID": 1003, "name": "王五", "age": 22}], "部门位置":"xx楼21号" }
- 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使用
Json格式数据解析相关推荐
- 导入数据任务(id:373985)异常, 错误信息:解析导入文件错误,请检查导入文件内容,仅支持导入json格式数据及excel文件
导入数据任务(id:373985)异常, 错误信息:解析导入文件错误,请检查导入文件内容,仅支持导入json格式数据及excel文件 参考文章: (1)导入数据任务(id:373985)异常, 错误信 ...
- python中json模块_Python使用内置json模块解析json格式数据的方法
本文实例讲述了Python使用内置json模块解析json格式数据的方法.分享给大家供大家参考,具体如下: Python中解析json字符串非常简单,直接用内置的json模块就可以,不需要安装额外的模 ...
- app开发历程————Android程序解析服务器端的JSON格式数据,显示在界面上
上一篇文章写的是服务器端利用Servlet 返回JSON字符串,本文主要是利用android客户端访问服务器端链接,解析JSON格式数据,放到相应的位置上. 首先,android程序的布局文件main ...
- 导入数据任务(id:373985)异常, 错误信息:解析导入文件错误,请检查导入文件内容,仅支持导入json格式数据及excel文件...
小程序导入,别人导出的数据库json文件,错误信息如下: 导入数据库失败, Error: Poll error, 导入数据任务(id:373985)异常,错误信息:解析导入文件错误,请检查导入文件内容 ...
- Ajax解析laravelJSON,3分钟短文:Laravel请求体内JSON格式数据的处理办法
原标题:3分钟短文:Laravel请求体内JSON格式数据的处理办法 引言 前几篇文章我们讲了表单数据的接收,验证等功能.也说到了传送的数组如何处理, 今天我们说一下如果传送的数据是JSON格式,其处 ...
- php使用 js格式解析,JavaScript解析JSON格式数据的方法示例
本文实例讲述了JavaScript解析JSON格式数据的方法.分享给大家供大家参考,具体如下: 1.使用JavaScript提供的eval()函数function JsonText1() { var ...
- 对JavaScript解析JSON格式数据的理解
对JavaScript解析JSON格式数据的理解 一.JSON与JavaScript对象的关系 1,JSON的由来: 在21世纪初,Douglas Crockford(Web开发领域最知名的技术权威之 ...
- JavaScript解析json格式数据简单示例
JavaScript解析json格式数据简单示例 本文通过for循环来获取json结点数据,需要的朋友可以参考以下这串json数据用来存储预加载的图片路径: 代码如下: var imgData = [ ...
- 【Python使用】Python解析JSON数据的基本方法/用MATLAB解析json格式数据
一 JSON数据格式介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. JSON建构于两种结构:json是Javascript中的对象和数组中的对象, ...
最新文章
- Py之xlwt:python库之xlwt的简介、安装、使用方法之详细攻略
- angular学习笔记之父子传值
- MySQL水表查询系统_水费管理系统
- WinRAR(WinZip)压缩与解压实现(C#版Window平台)
- 【转】Unity3D 关于贝赛尔曲线,平滑曲线,平滑路径,动态曲线
- 携程一次Redis迁移容器后Slowlog“异常”分析
- 【spine】原理介绍和程序实现
- NAT穿透的工作原理
- 辛普森法 matlab,MATLAB辛普森法则
- CSRNet: Dilated Convolutional Neural Networks for Understanding the Highly Congested Scen 论文阅读
- CAPM模型的Python版详解
- Linux下刻录cd,用debian命令刻录CD
- [TJOI2015]弦论
- 直播商城APP功能介绍
- C语言程序课程设计任务书
- 微信小程序--企业认证篇
- Spring Security技术栈开发企业级认证与授权-笔记
- Cisco Nexus 1000V, AVS , AVE的区别
- 探索 Flutter 模拟事件触发 | 开发者说·DTalk
- MYSQL 1366报错如何解决