为了实现客户端与服务器之间的数据交换,xml文件可能会成为首选,但是由于xml文件需要太多标签,造成资源上的冗余,因此,就放弃了xml文件,那么第二种可能会选择序列化和反序列化,IO流就是一种代表,实现了从磁盘到内存之间的交互,但是,如果基于不同语言或不同平台,那么序列化进行数据交互就无法实现。由此就出现了JSON,它是基于 ECMAScript的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
简单的来说,就是一种由多个键值对组成的集合。
最外部使用“{}”保存对象,每个对象由若干个数据组成。
每个数据由key:value键值对组成。
数据之间使用“,”分隔。
使用“\”进行特殊字符的转义。
示例如下:
{
"today": {
"temperature": "23℃~29℃",
"weather": "多云转雷阵雨",
"weather_id": {
"fa": "01",
"fb": "04"
},
"wind": "南风微风",
"week": "星期一",
"city": "北京",
"date_y": "2022年07月11日",
"dressing_index": "热",
"dressing_advice": "天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。",
"uv_index": "弱",
"comfort_index": "",
"wash_index": "较适宜",
"travel_index": "较适宜",
"exercise_index": "较适宜",
"drying_index": ""
}
}
}
使用fastjson,这是阿里巴巴的开源解析库。它可以解析JSON格式的字符串,也可以将某个实体类序列化成JSON格式的字符串(JSON.toJSONString(Objecct object)),也可以把JSON格式的字符串反序列化成对应的实体类(JSON.parseObject(String text))。
import com.fulian.entity.PoliceStation;
public class Test01 {
public static void main(String[] args) {
PoliceStation ps1 = new PoliceStation();
ps1.setName("电子城派出所");
ps1.setAddr("电子二路232号");
ps1.setTel("1343525342");
// 序列化:将Java对象转换成JSON格式的数据
String json1 = JSON.toJSONString(ps1);
System.out.println(json1);
// 反序列化:将JSON格式的字符串传换成Java对象
String jsonStr = "{\"addr\":\"沙井村232号\",\"name\":\"沙井村派出所\",\"tel\":\"029-7897588\"}";
PoliceStation ps2 = JSON.parseObject(jsonStr, PoliceStation.class);
System.out.println(ps2);
}
}
// 运行结果
// {"addr":"电子二路232号","name":"电子城派出所","tel":"1343525342"}
// PoliceStation [name=沙井村派出所, addr=沙井村232号, tel=029-7897588]
同时,fastjson也提供了两个类,JSONObject类和JSONArray类。
JSONObject类主要用于封装key-value键值对数据,它继承自LinkedHashMap接口。
package com.fulian.test;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
public class Test02 {
public static void main(String[] args) {
String jsonStr = "{\"temperature\":\"24℃~39℃\",\"weather\":\"小雨\",\"weather_id\":{\"fa\":\"07\",\"fb\":\"07\"},\"wind\":\"东北风3-5级\",\"week\":\"星期一\",\"city\":\"西安\",\"date_y\":\"2022年07月11日\",\"dressing_index\":\"炎热\",\"dressing_advice\":\"天气炎热,建议着短衫、短裙、短裤、薄型T恤衫等清凉夏季服装。\",\"uv_index\":\"弱\",\"comfort_index\":\"\",\"wash_index\":\"不宜\",\"travel_index\":\"较不宜\",\"exercise_index\":\"较不宜\",\"drying_index\":\"\"}";
// JSONObject继承自LinkedHashMap
JSONObject weatherJsonObj = JSON.parseObject(jsonStr);
// 根据key获取对应的value
String wind = weatherJsonObj.getString("wind");
System.out.println("风力: " + wind);
}
}
// 运行结果
// 风力: 东北风3-5级
JSONArray类主要用于封装数组集合类的数据,它继承自ArrayList类。
package com.fulian.test;
import java.util.Iterator;
import java.util.List;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fulian.entity.PoliceStation;
public class Test03 {
public static void main(String[] args) {
String data = "{\r\n" +
"\"title\":\"上海市政派出所信息\",\r\n" +
"\"list\":[\r\n" +
"{\r\n" +
"\"name\":\"文保分局沪东高校派出所\",\r\n" +
"\"addr\":\"中山北一路801号\",\r\n" +
"\"tel\":\"22027732\"\r\n" +
"},\r\n" +
"{\r\n" +
"\"name\":\"轨道分局人民广场站派出所\",\r\n" +
"\"addr\":\"南京西路19号\",\r\n" +
"\"tel\":\"63189188*76369\"\r\n" +
"},\r\n" +
"{\r\n" +
"\"name\":\"轨道分局陆家嘴站派出所\",\r\n" +
"\"addr\":\"龙阳路1990号乙\",\r\n" +
"\"tel\":\"63189188*27132\"\r\n" +
"}]\r\n" +
"}";
JSONObject jsonObj = JSON.parseObject(data);
System.out.println(jsonObj.getString("title"));
// 遍历方式1
// 获取key为list的value值(集合)
JSONArray jsonArray = jsonObj.getJSONArray("list");
// 获取该集合的元素个数
System.out.println(jsonArray.size());
// 遍历
for(int i = 0; i < jsonArray.size();i++) {
JSONObject item = jsonArray.getJSONObject(i);
System.out.println("派出所的名称:" + item.getString("name"));
System.out.println("派出所的地址:" + item.getString("addr"));
System.out.println("派出所的电话:" + item.getString("tel"));
System.out.println();
}
// 遍历方式2
List policeStationsLists = jsonObj.getList("list", PoliceStation.class);
System.out.println("上海市公安局:" + policeStationsLists.size());
for(PoliceStation ps : policeStationsLists) {
System.out.println(ps.getName());
System.out.println(ps.getAddr());
System.out.println(ps.getTel());
System.out.println();
}
}
}
解决办法:转换成JSON字符串时,使用feature(JSONWriter)枚举值进行判断
package com.fulian.test;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter.Feature;
public class Test06 {
public static void main(String[] args) {
// HashMap的匿名子类,通过构造代码块,初始化键值对
Map dataMap = new HashMap(){
{
// 构造代码块
put("age",18);
put("name","张三");
put("sex",null);
}
};
// // 默认过滤null值
// String json = JSON.toJSONString(dataMap);
// System.out.println(json);
String json = JSON.toJSONString(dataMap,Feature.WriteMapNullValue);
System.out.println(json);
}
}
// 运行结果
// {"sex":null,"name":"张三","age":18}
解决办法:使用@JSONField(ordinal = 1)注解形式,手动设置顺序
解决办法:使用@JSONField(format = "yyyy年MM月dd日 HH:mm:ss")注解形式,手动设置格式
package com.fulian.test;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter.Feature;
import com.alibaba.fastjson2.annotation.JSONField;
public class Test07 {
public static void main(String[] args) {
Order myOrder = new Order();
String json = JSON.toJSONString(myOrder,Feature.WriteMapNullValue,Feature.WriteNullNumberAsZero,Feature.WriteNullListAsEmpty);
System.out.println(json);
}
}
class Order{
@JSONField(ordinal = 1)
private String orderId;
@JSONField(ordinal = 2)
private Double pay;
@JSONField(ordinal = 3,format = "yyyy年MM月dd日 HH:mm:ss")
private LocalDateTime creationTime;
@JSONField(ordinal = 4)
private List address;
public Order() {
this.orderId = UUID.randomUUID().toString();
this.creationTime = LocalDateTime.now();
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public Double getPay() {
return pay;
}
public void setPay(Double pay) {
this.pay = pay;
}
public LocalDateTime getCreationTime() {
return creationTime;
}
public void setCreationTime(LocalDateTime creationTime) {
this.creationTime = creationTime;
}
public List getAddress() {
return address;
}
public void setAddress(List address) {
this.address = address;
}
}
// 运行结果
// {"orderId":"055a76de-ed68-4638-a811-2100bdd468d9","pay":0,"creationTime":"2022年07月11日 19:33:39","address":[]}