JSON: JavaScript Object Notation(JavaScript 对象表示法)
JSON 是存储和交换文本信息的语法。类似 XML。
JSON 比 XML 更小、更快,更易解析。
JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。 目前非常多的动态(PHP,JSP,.NET)编程语言都支持JSON。
1. JSON语法
JSON 语法规则
数据在名称/值对中
数据由逗号分隔
花括号保存对象
方括号保存数组
JSON 名称/值对
JSON 数据的书写格式是:名称/值对。
名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值:
“name” : “zhangsan”
这很容易理解,等价于这条 JavaScript 语句:
name = "zhangsan"
JSON 值类型
JSON 值可以是:
字符串(在双引号中)
数字(整数或浮点数)
对象(在花括号中)
数组(在方括号中)
逻辑值(true 或 false)
2. JSON的数据结构
JSON有两种数据结构:对象和数组。
JSON对象
对象是一个无序的“‘名称/值’对”集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
JSON 对象在花括号中书写:
{ "name":"zhangsan" , "age":24 }
这一点也容易理解,与这条 JavaScript 语句等价:
name = "zhangsan"
age = 24
JSON数组
值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
JSON 数组在方括号中书写:
数组可包含多个对象:
"people"
: [
{
"namr":"zhangsan" , "age":22
},
{
"name":"lisi" , "age":24
},
{
"name":"wangwu" , "age":27
}
在上面的例子中,对象 "employees" 是包含三个对象的数组。每个对象代表一条关于某人(有姓和名)的记录。
二、Java 中操作 JSON 数据
网上有很多JAVA种操作JSON的jar包,比较流行的类库Jackson、Gson和FastJSON。
注意:在Maven的中的引用量,FastJSON和Jackson和Gson不在一个数量级,据说是一个代码质量不高的国产类库,还是存在较多的问题的。
这里就介绍下Jackson和Gson。
1. Jackson
Jackson提供了三种可选的JSON处理方法:
流式API
com.fasterxml.jackson.core.JsonParser读 -- 通过JsonFactory构建
com.fasterxml.jackson.core.JsonGenerator写 -- 通过JsonFactory构建
树模型:提供一个 JSON 文档可变内存树的表示形式
com.fasterxml.jackson.databind.ObjectMapper生成树 ;树组成 JsonNode 节点集
树模型类似于 XML DOM。
数据绑定:JSON和POJO相互转换,基于属性访问器规约或注解
有两种变体:简单和完整的数据绑定
简单数据绑定:是指从Java Map、List、String、Numbers、Boolean和空值进行转换
完整数据绑定:是指从任何Java bean 类型(及上文所述的"简单"类型)进行转换
com.fasterxml.jackson.databind.ObjectMapper对两个变种进行编排(marshalling)处理(写入JSON)和反编排(unmarshalling读JSON)。
3 种方法的用法如下
流 API: 性能最佳的方式 (最低开销、 速度最快的读/写; 其它二者基于它实现)。
数据绑定 :使用最方便的方式。
树模型: 最灵活的方式。
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</version>
</dependency>
使用JsonGenerator写入JSON
JsonFactory factory = new JsonFactory();
//JsonGenerator 定义公共API编写的Json内容的基类。使用JsonFactory实例的工厂方法创建实例(createGenerator)。
JsonGenerator jsonGenerator = factory.createGenerator(new File("D:\\idea_workspace\\springboot\\ComJava\\src\\main\\resources\\student.json"), JsonEncoding.UTF8);
jsonGenerator.writeStartObject();
// "name" : "harvey"
jsonGenerator.writeStringField("name", "harvey");
// "age" : 20
jsonGenerator.writeNumberField("age", 20);
// "isMan" : false
jsonGenerator.writeBooleanField("isMan", false);
// "marks" : [20, 5, 40]
jsonGenerator.writeFieldName("marks");
jsonGenerator.writeStartArray();
//20, 5, 40
jsonGenerator.writeNumber(20);
jsonGenerator.writeNumber(5);
jsonGenerator.writeNumber(40);
jsonGenerator.writeEndArray();
jsonGenerator.writeEndObject();
jsonGenerator.close();
JsonFactory factory = new JsonFactory();
//JsonGenerator 定义公共API编写的Json内容的基类。使用JsonFactory实例的工厂方法创建实例(createGenerator)。
JsonGenerator jsonGenerator = factory.createGenerator(new File("D:\\idea_workspace\\springboot\\ComJava\\src\\main\\resources\\student.json"), JsonEncoding.UTF8);
jsonGenerator.writeStartObject();;
// "students": []
jsonGenerator.writeFieldName("students");
jsonGenerator.writeStartArray();
//如果有多个对象,这里循环即可
jsonGenerator.writeStartObject();;
// "name" : "harvey"
jsonGenerator.writeStringField("name", "harvey");
// "age" : 20
jsonGenerator.writeNumberField("age", 20);
// "isMan" : false
jsonGenerator.writeBooleanField("isMan", false);
jsonGenerator.writeEndObject();;
jsonGenerator.writeEndArray();
jsonGenerator.writeEndObject();;
jsonGenerator.close();
使用JsonParser 读取JSON
JsonFactory factory = new JsonFactory();
//JsonParser 定义公共API用于读取的Json内容的基类。使用JsonFactory实例的工厂方法创建实例(createParser)。
JsonParser jsonParser = factory.createParser(new File("D:\\idea_workspace\\springboot\\ComJava\\src\\main\\resources\\student.json"));
while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
//get the current token
String fieldName = jsonParser.getCurrentName();
if ("name".equals(fieldName)) {
//move to next token
jsonParser.nextToken();
System.out.println(jsonParser.getText());
if("age".equals(fieldName)){
//move to next token
jsonParser.nextToken();
System.out.println(jsonParser.getNumberValue());
if("isMan".equals(fieldName)){
//move to next token
jsonParser.nextToken();
System.out.println(jsonParser.getBooleanValue());
if("marks".equals(fieldName)){
//move to [
jsonParser.nextToken();
// loop till token equal to "]"
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
System.out.println(jsonParser.getNumberValue());
树到JSON转换
ObjectMapper mapper = new ObjectMapper();
String jsonString = "{\"name\":\"Mahesh Kumar\", \"age\":21,\"verified\":false,\"marks\": [100,90,85]}";
JsonNode rootNode = mapper.readTree(jsonString);
JsonNode nameNode = rootNode.path("name");
System.out.println("Name: "+ nameNode.asText());
JsonNode ageNode = rootNode.path("age");
System.out.println("Age: " + ageNode.asInt());
JsonNode verifiedNode = rootNode.path("verified");
System.out.println("Verified: " + (verifiedNode.asBoolean() ? "Yes":"No"));
JsonNode marksNode = rootNode.path("marks");
Iterator<JsonNode> iterator = marksNode.iterator();
System.out.print("Marks: [ ");
while (iterator.hasNext()) {
JsonNode marks = iterator.next();
System.out.print(marks.asInt() + " ");
System.out.println("]");
通常都是json字符串与对象的相互转换。
ObjectMapper convertMapper = new ObjectMapper();
//对象转json
convertMapper.writeValueAsString(Object value);
//json转对象
convertMapper.readValue(String content, Class<T> valueType)
对象序列化
Student student = new Student();
student.setAge(10);
student.setName("Harvey");
//对象序列化
ObjectMapper mapper = new ObjectMapper();
//示例一
mapper.writeValue(new File("D:\\idea_workspace\\springboot\\ComJava\\src\\main\\resources\\student.json"), student);
// 还有其他形式
// void writeValue(OutputStream out, Object value)
// void writeValue(Writer w, Object value)
// String writeValueAsString(Object value)
// byte[] writeValueAsBytes(Object value)
//示例二
Student readStudent = mapper.readValue(new File("D:\\idea_workspace\\springboot\\ComJava\\src\\main\\resources\\student.json"), Student.class);
System.out.println(readStudent.getName());
// 还有其他形式
// <T> T readValue(String content, Class<T> valueType)
// <T> T readValue(byte[] src, Class<T> valueType)
//实体类
class Student {
private String name;
private int age;
public Student(){}
public String getName() {
return name;
public void setName(String name) {
this.name = name;
public int getAge() {
return age;
public void setAge(int age) {
this.age = age;
public String toString(){
return "Student [ name: "+name+", age: "+ age+ " ]";
2. Gson
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
gson实例化的两种方式
Gson gson = new Gson();
Gson gson = new GsonBuilder()
.setLenient()// json宽松
.enableComplexMapKeySerialization()//支持Map的key为复杂对象的形式
.serializeNulls() //智能null
.setPrettyPrinting()// 调教格式
.disableHtmlEscaping() //默认是GSON把HTML转义的
.create();
Bean、Map、List的相互转换
Gson提供了fromJson() 和toJson() 两个直接用于解析和生成的方法,前者实现反序列化,后者实现了序列化;同时每个方法都提供了重载方法。
Gson的注解
注:在Gson中有5类注解 。
@SerializedName注解(JSON字段重命名)
该注解能指定该字段在JSON中对应的字段名称,就是将POJO中的字段与JSON字符串中的字段对应起来。
输出的json使用另外一个名字,默认转换出来的json中和对象的字段是一样的,当然也可以设置成不同,使用SerializedName 注解 。
@Expose注解(字段过滤)
指定哪些是要暴露转换的属性。有时候我们不需要把实体的所有属性都导出,只想把一部分属性导出为Json,或只想对一部分POJO的字段进行反序列化。
@Since(double v) 与 @Until(double v)注解 (版本控制)
有时候我们的实体类会随着版本的升级而修改。一些新的字段是后续加进来的,在新的版本软件中才使用。
JsonAdapter注解 (使用TypeAdapter时的注解)
https://www.cnblogs.com/jingmoxukong/p/4664224.html
时刻与技术进步,每天一点滴,日久一大步!!!
本博客只为记录,用于学习,如有冒犯,请私信于我。