第七篇:JSON解析永不眠

一、前言

本文一共介绍JSON两种解析方式、JSON合法性验证的一个网站、JSONArray中删除元素、JSONObject中删除键值对,开发中基本上够用了。

二、JSON解析与JSON合法性验证

2.1 使用org.json解析

一共包括org.json.JSONArray、org.json.JSONObject两个类,看一个同时包含JSONObject、JSONArray的。

代码:

package com.csdn.example.JSONparsePackage1;

import org.json.JSONArray;
import org.json.JSONObject;

/**
 * Created by maoqizhi on 2020/7/22.
 */
public class JSONParser3 {
    public static void main(String[] args) {
        //待解析的JSON字符串
        String JSONString = "{'name':'卢本伟','age':24,'Hero':{'name':'Fizz','Position':'Mid','charactor':'killer'},'nickNames':['五五开','芦苇','white'],'Honors':[{'year':2011,'name':'TGA总决赛冠军'},{'year':2013,'name':'S3全球总决赛中国区冠军'},{'year':2013,'name':'S3全球总决赛亚军'}]}";

        try {

            JSONObject JSON = new JSONObject(JSONString);      // 第一步,将string变为JSON  这里最外层是{  所以是new JSONObject

        /*
         * 普通元素,getXxx()直接获取
         */
            String name = JSON.getString("name");
            int age = JSON.getInt("age");
            System.out.println("姓名:"+name);
            System.out.println("年龄:"+age);
            System.out.println("————————————————————————————————");

        /*
         * 属性大括号包括,先获取JSONObject对象  getJSONObject()  然后进一步getXxx()解析属性
         */
            JSONObject hero = JSON.getJSONObject("Hero");
            String hero_name = hero.getString("name");
            String hero_position = hero.getString("Position");
            String hero_charactor = hero.getString("charactor");
            System.out.println("擅长英雄:");
            System.out.println("英雄名:"+hero_name);
            System.out.println("位置:"+hero_position);
            System.out.println("英雄定位:"+hero_charactor);
            System.out.println("————————————————————————————————");

        /*
         * 属性被中括号包括,获取JSONArray对象,getJSONArray  ,然后进一步遍历即可
         */
            System.out.println("外号:");
            JSONArray nickNames = JSON.getJSONArray("nickNames");
            for (Object nickName : nickNames) {
                System.out.println(nickName);
            }
            System.out.println("————————————————————————————————");

        /*
         * 属性中既有中括号包括,又嵌套了大括号,一层层获取即可   先getJSONArray,然后getJSONObject,到了属性,就是getXxx()了
         */
            JSONArray Honors = JSON.getJSONArray("Honors");
            System.out.println("所获荣誉:");
            for(int i=0;i<Honors.length();i++)
            {
                JSONObject honor = Honors.getJSONObject(i);
                int honor_year = honor.getInt("year");
                String honor_name = honor.getString("name");
                System.out.println(honor_year+" : "+ honor_name);
            }
        }catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
    }
}

使用org.json包解析的王道小结:

第一步,如果{ 开头,new JSONObject(JSONString);,如果是是 [ 开头,new JSONArray(JSONString);

第二步,一层一层来,四种情况:
key:value 当前对象.get("xxx");
key:JSONObject对象 当前对象.getJSONObject("xxx");
key:JSONArray对象 当前对象.getJSONArray("xxx");
value foreach(Object each:当前对象)

问题1:为什么将JSON格式用来不同语言的通信?

回答1:因为在不同的语言当中,都可以将JSON数据转换成JSON对象,转成JSON对象之后,想获取JSONObj对象中的某个值(假设转换成JSON对象的对象名为JSONObj),那么想要获取request的值"login",直接JSONObj.request就可以了。

问题2:对于Java,怎么来实现JSON数据的传输呢?

回答2:Java对象是不能直接传输的,只有把JSON对象,转成字符串,传输之后,到另一方再将字符串又转成JSON,才能完成整个传输过程。JSON格式是很多语言都支持的,很多语言直接可以互转的,就这样,JSON就是这样完成跨语言的数据通信。

问题3:为什么不同语言都不约而同的支持JSON格式?

回答3:因为JSON格式本质上就是一个map。

2.2 使用com.alibaba.fastjson解析

fastjson是阿里巴巴开源产品之一,解析速度快。

代码:

package com.csdn.example.JSONparsePackage2;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * Created by maoqizhi on 2020/7/22.
 */
public class JSONParser3 {
    public static void main(String[] args) {


        String JSONString = "{'name':'卢本伟','age':24,'Hero':{'name':'Fizz','Position':'Mid','charactor':'killer'},'nickNames':['五五开','芦苇','white'],'Honors':[{'year':2011,'name':'TGA总决赛冠军'},{'year':2013,'name':'S3全球总决赛中国区冠军'},{'year':2013,'name':'S3全球总决赛亚军'}]}";


        JSONObject JSON = JSON.parseObject(JSONString);      // 第一步,将string变为JSON  这里最外层是{  所以是new JSONObject

        /*
         * 普通元素,getXxx()直接获取
         */
        String name = JSON.getString("name");
        int age = JSON.getIntValue("age");
        System.out.println("姓名:" + name);
        System.out.println("年龄:" + age);
        System.out.println("————————————————————————————————");

        /*
         * 属性大括号包括,先获取JSONObject对象  getJSONObject()  然后进一步getXxx()解析属性
         */
        JSONObject hero = JSON.parseObject("" + JSON.get("Hero"));

        String hero_name = hero.getString("name");
        String hero_position = hero.getString("Position");
        String hero_charactor = hero.getString("charactor");
        System.out.println("擅长英雄:");
        System.out.println("英雄名:" + hero_name);
        System.out.println("位置:" + hero_position);
        System.out.println("英雄定位:" + hero_charactor);
        System.out.println("————————————————————————————————");

        /*
         * 属性被中括号包括,获取JSONArray对象,getJSONArray  ,然后进一步遍历即可
         */
        System.out.println("外号:");

        JSONArray nickNames = JSON.parseArray("" + JSON.get("nickNames"));


        for (Object nickName : nickNames) {
            System.out.println(nickName);
        }
        System.out.println("————————————————————————————————");

        /*
         * 属性中既有中括号包括,又嵌套了大括号,一层层获取即可   先getJSONArray,然后getJSONObject,到了属性,就是getXxx()了
         */

        JSONArray Honors = JSON.parseArray("" + JSON.get("Honors"));
        System.out.println("所获荣誉:");
        for (int i = 0; i < Honors.size(); i++) {
            JSONObject honor = (JSONObject) Honors.get(i);

            int honor_year = honor.getIntValue("year");
            String honor_name = honor.getString("name");
            System.out.println(honor_year + " : " + honor_name);
        }

    }
}

使用org.json包解析的王道小结:

第一步,如果{ 开头,JSON.parseObject(JSONString);;如果是是 [ 开头,JSON.parseArray(JSONString);

第二步,一层一层来,四种情况:
key:value 当前对象.getString("xxx"); // 不能直接使用get,一定要加上类型
key:JSONObject对象 JSON.parseObject(""+xxx); // 参数一定是字符串
key:JSONArray对象 JSON.parseArray(""+xxx); // 参数一定是字符串
value foreach(Object each:当前对象)

小结:fastjson中,JSON.toJSON(xxx).toString() 或 JSON.toJSONString(xxx) xxx(model对象或map对象)得到 json 对象,json 其实就是 string 字符串;
JSON.parseObject 则将 字符串 变为 json 或者 将 字符串 转换为 model对象(包括map对象)
其中, JSONObject JSON = JSON.parseObject(JSONString); 将字符串转为json对象;
Xxx xxx = JSON.parseObject(JSONString,Xxx.class); 将字符串转为model对象。

2.3 JSON合法性验证

提供一个JSON合法性验证网站: http://www.beJSON.com/,该网站可以验证JSON合法性(当然,类似的网站还有很多),这里是该网站截图:
在这里插入图片描述

三、JSONArray中删除元素、JSONObject中删除元素

3.1 JSONArray中删除元素

3.1.1 初级办法:foreach遍历JSONArray,新建一个存放不需要删除的元素

JSONArray JSONarray = new JSONArray();
Set<Object> JSONObjects = new HashSet<>();
for (Object obj : JSONarray) {
	JSONObject JSONObject = JSONObject.parseObject(JSONObject.toJSONString(obj));
	if (JSONObject.containsKey("key")) {
	    JSONObjects.add(JSONObject);
    }
}
JSONarray.removeAll(JSONObjects);

3.1.2 高级办法:遍历iterator

Iterator<Object> o = ja.iterator();
while (o.hasNext()) {
    JSONObject jo = (JSONObject) o.next();
    if(jo.getIntValue("key") == 325) {
        //ja.remove(jo); //不要用这种方式删除,会报出ConcurrentModificationException
        o.remove(); //这种方式OK的
    }
}
System.out.println(ja);

org.json 可以使用这种方式删除并更新
在这里插入图片描述

com.alibaba.fastjson也可以使用这种方式删除并更新
在这里插入图片描述

3.2 JSONObject中删除键值对

业务需求:在登录时为了不让用户看看到明文密码,当后台返回的是JSON格式的字符串,我们可以将JSON格式的字符串转换成JSON对象操作移除“password”,从下面数据中将“password”移除返回。

{"code":null,
"data":[{"password":"123","role":"aiyo","org":"caizhengju",
"createTime":"2016-08-13 00:36:27.0","nickname":"123",
"userId":"20B38E63-0B19-B465-3A98-64FEE841FDEC",
"username":"123"},{"password":"44","role":"lala","org":"sifaju",
"createTime":"2016-08-12 02:42:39.0","nickname":"44",
"userId":"8AFC589E-5080-4E25-41E4-139A765CA9D1","username":"44"}],
"success":true,"mgs":"查询成功"}

设result内容为以上JSON字符串,先获取其data的内容,如下:

JSONObject JSONObject=new JSONObject(s); //可以将JSON格式的字符串变成JSON对象
JSONArray JSONArray= (JSONArray) JSONObject.get("data");

输出JSONArray为:

[{"password":"123","role":"aiyo","org":"caizhengju",
"createTime":"2016-08-13 00:36:27.0","nickname":"123",
"userId":"20B38E63-0B19-B465-3A98-64FEE841FDEC",
"username":"123"},{"password":"44","role":"lala","org":"sifaju",
"createTime":"2016-08-12 02:42:39.0","nickname":"44",
"userId":"8AFC589E-5080-4E25-41E4-139A765CA9D1",
"username":"44"}]

实现:用一个for循环移除“数组中的password”,如下:

for (int i=0;i<JSONArray.length();i++) {
    JSONObject JSONData = (JSONObject) JSONArray.get(i);//得到对象中的第i条记录
    System.out.println("data[" + i + "]:" +    JSONData.remove("password"));
}

输出:

data[0]:123
data[1]:44

原来以为移除后需要把JSONArray对象put进JSONObject中,其实并不需要,移除后的JSONObject就已经在原来的对象中移除掉“password”。

System.out.println(String.valueOf(JSONObject));

输出:

{"code":null,"data":[{"role":"aaaaa","org":"nongyeju","createTime":"2016-08-12 01:39:44.0","nickname":"33","userId":"7B5FBB51-F93E-DEC2-BBBF-70480A3A9AF5","username":"33"}],"success":true,"mgs":"查询成功"}

这样就成功把password去除,完成了。

四、尾声

JSON解析永不眠,完成了。

天天打码,天天进步!!!

源工程代码:https://download.csdn.net/download/qq_36963950/12654714

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祖母绿宝石

打赏一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值