Bootstrap

使用Java解析JSON

        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部分类似,暂不展开解析。

;