在Java中解析JSON对象

100

我有一个如下的JSON对象:

member = "{interests : [{interestKey:Dogs}, {interestKey:Cats}]}";
在Java中,我想解析上述JSON对象并将其值存储在ArrayList中。 我正在寻找一些代码来实现这一点。

请查看以下链接:https://androidbeasts.wordpress.com/2015/08/04/json-parsing-tutorial/ - Aakash
这是一个简短的视频,演示了如何使用org.json库解析json。 - drorw
5个回答

158

我假定你想要将interestKeys存储在一个列表中。

使用org.json库:

JSONObject obj = new JSONObject("{interests : [{interestKey:Dogs}, {interestKey:Cats}]}");

List<String> list = new ArrayList<String>();
JSONArray array = obj.getJSONArray("interests");
for(int i = 0 ; i < array.length() ; i++){
    list.add(array.getJSONObject(i).getString("interestKey"));
}

9
org.json 的性能是所有库中最差的之一,而且该库是在 JSON 早期开发阶段作为概念证明而开发的。 选择一个性能表现良好的 json 库:https://github.com/fabienrenaud/java-json-benchmark - fabien
@fabien,那些org.json的基准测试似乎是使用版本20090211完成的。也许它的性能在过去的10年中有所提高? - Alistair Jones

13
public class JsonParsing {

public static Properties properties = null;

public static JSONObject jsonObject = null;

static {
    properties = new Properties();
}

public static void main(String[] args) {

    try {

        JSONParser jsonParser = new JSONParser();

        File file = new File("src/main/java/read.json");

        Object object = jsonParser.parse(new FileReader(file));

        jsonObject = (JSONObject) object;

        parseJson(jsonObject);

    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public static void getArray(Object object2) throws ParseException {

    JSONArray jsonArr = (JSONArray) object2;

    for (int k = 0; k < jsonArr.size(); k++) {

        if (jsonArr.get(k) instanceof JSONObject) {
            parseJson((JSONObject) jsonArr.get(k));
        } else {
            System.out.println(jsonArr.get(k));
        }

    }
}

public static void parseJson(JSONObject jsonObject) throws ParseException {

    Set<Object> set = jsonObject.keySet();
    Iterator<Object> iterator = set.iterator();
    while (iterator.hasNext()) {
        Object obj = iterator.next();
        if (jsonObject.get(obj) instanceof JSONArray) {
            System.out.println(obj.toString());
            getArray(jsonObject.get(obj));
        } else {
            if (jsonObject.get(obj) instanceof JSONObject) {
                parseJson((JSONObject) jsonObject.get(obj));
            } else {
                System.out.println(obj.toString() + "\t"
                        + jsonObject.get(obj));
            }
        }
    }
}}

我想我尽力使它动态化,希望它能解决你的问题。 - Code
1
现在,您可以将parseJson和getArray的返回类型更改为String,并将它们添加到ArrayList中,稍后可以迭代该列表以获取所需数据 :) - Code

7
非常感谢 @Code 在另一个答案中的帮助。通过您的代码,我现在可以读取任何JSON文件了。现在,我正在尝试按层级组织所有元素,以便能够使用它们!
我正在处理Android,从URL读取JSON,唯一需要更改的是以下这几行: Set<Object> set = jsonObject.keySet(); Iterator<Object> iterator = set.iterator(); 更改为: Iterator<?> iterator = jsonObject.keys(); 我分享我的实现方式,以帮助其他人:
public void parseJson(JSONObject jsonObject) throws ParseException, JSONException {

    Iterator<?> iterator = jsonObject.keys();
    while (iterator.hasNext()) {
        String obj = iterator.next().toString();

        if (jsonObject.get(obj) instanceof JSONArray) {
            //Toast.makeText(MainActivity.this, "Objeto: JSONArray", Toast.LENGTH_SHORT).show();
            //System.out.println(obj.toString());
            TextView txtView = new TextView(this);
            txtView.setText(obj.toString());
            layoutIzq.addView(txtView);
            getArray(jsonObject.get(obj));
        } else {
            if (jsonObject.get(obj) instanceof JSONObject) {
                //Toast.makeText(MainActivity.this, "Objeto: JSONObject", Toast.LENGTH_SHORT).show();
                parseJson((JSONObject) jsonObject.get(obj));
            } else {
                //Toast.makeText(MainActivity.this, "Objeto: Value", Toast.LENGTH_SHORT).show();
                //System.out.println(obj.toString() + "\t"+ jsonObject.get(obj));
                TextView txtView = new TextView(this);
                txtView.setText(obj.toString() + "\t"+ jsonObject.get(obj));
                layoutIzq.addView(txtView);
            }
        }
    }
}

6

1.) 创建一个适当类型的ArrayList,本例中为String

2.) 创建一个JSONObject,将您的字符串作为输入传递给JSONObject构造函数

  • JSONObject表示为大括号,即{}
  • JSONArray表示为方括号,即[]

3.) 使用"interests"作为索引从第二步创建的JSONObject中检索JSONArray

4.) 使用循环遍历JASONArray,直到达到由length()函数提供的数组长度。

5.) 使用getJSONObject(index)函数从JSONArray中检索您的JSONObjects

6.) 使用索引'"interestKey"'从JSONObject中获取数据。

注意:如果json响应(通常来自其他JSON响应API)包含引号("),则JSON解析使用特殊嵌套字符的转义序列。

`"{"key":"value"}"`

应该是这样的

`"{\"key\":\"value\"}"`

因此,您可以使用JSONParser来实现转义序列格式以提高安全性。

JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(inputString);

Code :

JSONParser parser = new JSONParser();
String response = "{interests : [{interestKey:Dogs}, {interestKey:Cats}]}";

JSONObject jsonObj = (JSONObject) parser.parse(response);

或者
JSONObject jsonObj = new JSONObject("{interests : [{interestKey:Dogs}, {interestKey:Cats}]}");

List<String> interestList = new ArrayList<String>();

JSONArray jsonArray = jsonObj.getJSONArray("interests");

for(int i = 0 ; i < jsonArray.length() ; i++){
    interestList.add(jsonArray.getJSONObject(i).optString("interestKey"));
}

注意:有时候当值不是适当的类型或没有映射键时,你可能会看到一些异常情况。在这种情况下,如果你不确定值是否存在,请使用optString、optInt、optBoolean等方法,它们会简单地返回默认值(如果不存在),并尝试将值转换为int(如果它是字符串类型)等,因此在缺少键或值的情况下根本不会出现空指针或NumberFormat异常。请参考文档:文档

Get an optional string associated with a key. It returns the defaultValue if there is no such key.

 public String optString(String key, String defaultValue) {
  String missingKeyValue = json_data.optString("status","N/A");
  // note there is no such key as "status" in response
  // will return "N/A" if no key found 

或者,如果没有找到键,则可以直接使用空字符串,即""

  String missingKeyValue = json_data.optString("status");
  // will return "" if no key found where "" is an empty string

进一步参考研究


3
在Java中有许多可用的JSON库。其中最出名的是:Jackson、GSON、Genson、FastJson和org.json。
通常在选择任何库时应考虑以下三个方面: 1. 性能 2. 易用性(代码编写简单易读)-这与功能相关。 3. 对于移动应用程序:依赖/ jar大小
特别是对于JSON库(以及任何序列化/反序列化库),数据绑定也通常是感兴趣的,因为它消除了编写打包/解包数据的样板代码的需要。
有关性能,请参见此基准测试:https://github.com/fabienrenaud/java-json-benchmark我使用JMH进行了比较(jackson、gson、genson、fastjson、org.json、jsonp)序列化器和反序列化器的性能,并使用流和databind API进行比较。
有关易用性,请参阅互联网上的众多示例。上述基准测试也可以用作示例的来源...
基准测试的快速结论:Jackson的性能比org.json高5到6倍,比GSON高两倍以上。
对于您的特定示例,请使用以下代码使用jackson解码json:
public class MyObj {

    private List<Interest> interests;

    static final class Interest {
        private String interestKey;
    }

    private static final ObjectMapper MAPPER = new ObjectMapper();
    public static void main(String[] args) throws IOException {
        MyObj o = JACKSON.readValue("{\"interests\": [{\"interestKey\": \"Dogs\"}, {\"interestKey\": \"Cats\" }]}", MyObj.class);
    }
}

如果您有任何问题,请告知我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接