JSON全称为Java Script Object NoTation。它作为一种轻量级的数据交换格式,它被广泛应用于各种平台,在两个系统之间交换数据起到不可或缺的作用。JSON具有两种结构:JSON对象和JSON集合。JSON对象为{key:value,key:value,...}的键值对形式,key为对象的属性,value为对应的属性的值。JSON集合为["Java","JSON","Apesource"]的形式,取值方式和所有语言相同,同过索引获取,字段值的类型可以为字符串、数字、数组、对象等等。同时,JSON不支持注释。并且,JSON数据可以和js数据一样形成JSON文件。
JSON数据有以下几个优点:
1、JSON中使用UTF-8编码,所以不存在转码问题。
2、JSON内容仅包含key-value键值对,格式简单,不存在冗余结构。
3、浏览器内置JSON支持,如果把数据发给浏览器,可以用JavaScript直接处理。
在Java中解析JSON个人推荐使用的第三方库有,FastJSON、Jackson,FastJSON是阿里巴巴开源的JSON解析库,它可以解析JSON格式的字符串,支持将JavaBean“序列化”为JSON数据,也可以将JSON数据“反序列化”为JavaBean。
JavaBean“序列化”为JSON数据主要通过toJSONString()方法。
toJSONString方法源码如下:
static String toJSONString(Object object) {
try (JSONWriter writer = JSONWriter.of()) {
if (object == null) {
writer.writeNull();
} else {
Class<?> valueClass = object.getClass();
ObjectWriter<?> objectWriter = writer.getObjectWriter(valueClass, valueClass);
objectWriter.write(writer, object, null, null, 0);
}
return writer.toString();
} catch (NullPointerException | NumberFormatException ex) {
throw new JSONException("toJSONString error", ex);
}
}
例如,将一个PoliceStation实体类对象“序列化为”JSON数据
PoliceStation实体类
package com.apesource.entity;
// 派出所警局实体类
public class PoliceStation {
private String name; // 警局派出所的名称
private String addr; // 地址
private String tel; // 联系电话
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Override
public String toString() {
return "PoliceStation [name=" + name + ", addr=" + addr + ", tel=" + tel + "]";
}
}
“序列化”:
public class Demo01 {
public static void main(String[] args) {
PoliceStation psl = new PoliceStation();
psl.setAddr("北京市房山区");
psl.setName("房山区派出所");
psl.setTel("110");
// "序列化",将Java对象转换成json格式
String str = JSON.toJSONString(psl);
System.out.println(str);
结果如下:
JSON数据的字符串“反序列化”为JavaBean主要通过parseObject()方法
parseObject()源码如下:
@SuppressWarnings("unchecked")
static <T> T parseObject(String text, Class<T> clazz) {
if (text == null || text.isEmpty()) {
return null;
}
try (JSONReader reader = JSONReader.of(text)) {
JSONReader.Context context = reader.context;
boolean fieldBased = (context.features & JSONReader.Feature.FieldBased.mask) != 0;
ObjectReader<T> objectReader = context.provider.getObjectReader(clazz, fieldBased);
T object = objectReader.readObject(reader, 0);
if (reader.resolveTasks != null) {
reader.handleResolveTasks(object);
}
return object;
}
}
例如,将一个JSON数据的字符串“反序列化”为JavaBean
package com.apesource;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.apesource.entity.PoliceStation;
public class Demo01 {
public static void main(String[] args) {
// 反序列化,将json格式的字符串转换成JAVA对象
String strJson = "{\"addr\":\"北京市房山区\",\"name\":\"房山区派出所\",\"tel\":\"110\"}";
PoliceStation ps2 = JSON.parseObject(strJson, PoliceStation.class);
System.out.println(ps2);
}
结果如下:
在明确解析JSON数据后,我们可以尝试使用较为复杂的数据进行解析。
{
"sk": {
"temp": "32",
"wind_direction": "东北风",
"wind_strength": "5级",
"humidity": "53%",
"time": "14:38"
},
"today": {
"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": ""
},
"future": {
"day_20220711": {
"temperature": "24℃~39℃",
"weather": "小雨",
"weather_id": {
"fa": "07",
"fb": "07"
},
"wind": "东北风3-5级",
"week": "星期一",
"date": "20220711"
},
"day_20220712": {
"temperature": "24℃~27℃",
"weather": "小雨",
"weather_id": {
"fa": "07",
"fb": "07"
},
"wind": "北风微风",
"week": "星期二",
"date": "20220712"
},
"day_20220713": {
"temperature": "25℃~30℃",
"weather": "小雨",
"weather_id": {
"fa": "07",
"fb": "07"
},
"wind": "北风微风",
"week": "星期三",
"date": "20220713"
},
"day_20220714": {
"temperature": "25℃~34℃",
"weather": "阴转多云",
"weather_id": {
"fa": "02",
"fb": "01"
},
"wind": "东北风微风",
"week": "星期四",
"date": "20220714"
},
"day_20220715": {
"temperature": "25℃~34℃",
"weather": "阴转小雨",
"weather_id": {
"fa": "02",
"fb": "07"
},
"wind": "东北风4-5级",
"week": "星期五",
"date": "20220715"
},
"day_20220716": {
"temperature": "24℃~27℃",
"weather": "小雨",
"weather_id": {
"fa": "07",
"fb": "07"
},
"wind": "北风微风",
"week": "星期六",
"date": "20220716"
},
"day_20220717": {
"temperature": "25℃~34℃",
"weather": "阴转多云",
"weather_id": {
"fa": "02",
"fb": "01"
},
"wind": "东北风微风",
"week": "星期日",
"date": "20220717"
}
}
}
1.解析sk部分(sk部分是一个key-value形式的键值对对象)
可以使用JSONObject.get方法获取Json对象中的某个key对应的value
String sk = (String)jsonObj.get("sk");
2.解析today部分,观察得知,today部分为多层JSON对象的嵌套,所以需要逐层解析
Set<Entry<String, Object>> set1 = jsonFuture.entrySet();
for (Entry<String, Object> entry : set1) {
JSONObject jsonObj = (JSONObject)entry.getValue();
System.out.println("日期:" + jsonObj.getString("date"));
System.out.println("温度:" + jsonObj.getString("temperature"));
System.out.println("风力:" + jsonObj.getString("wind"));
System.out.println("天气:" + jsonObj.getString("weather"));
System.out.println();
}
3.future部分的解析与today部分类似,暂不展开解析。