从json串中获取某个值_JSON解析永不眠

ed0d9c4509bdf80fad8f1817c96c9fcb.png

一、前言

本文一共介绍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:当前对象)

2.3 JSON合法性验证

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

6d3ba8253a28a5c558aaf0d9d1b3c145.png

三、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 可以使用这种方式删除并更新

3458caac824c962c8b3ee86736b5b0ef.png

com.alibaba.fastjson也可以使用这种方式删除并更新

684590a90e8995a9d71d3d5ee20eb668.png

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解析永不眠,完成了。

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