【问题标题】:Parsing JSON Object in Java [duplicate]在Java中解析JSON对象[重复]
【发布时间】:2011-06-28 07:13:32
【问题描述】:

我有如下 JSON 对象:

member = "{interests : [{interestKey:Dogs}, {interestKey:Cats}]}";

在 Java 中我想解析上面的 json 对象并将值存储在一个数组列表中。

我正在寻找一些可以实现这一目标的代码。

【问题讨论】:

标签: java json


【解决方案1】:

我假设您想将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"));
}

【讨论】:

  • org.json 的性能是所有库中最差的 + lib 是在 JSON 的早期作为概念证明而开发的。选择性能良好的 json 库:github.com/fabienrenaud/java-json-benchmark
  • @fabien 那些 org.json 基准测试似乎是使用版本 20090211 完成的。也许它的表现在过去 10 年有所改善?
【解决方案2】:
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));
            }
        }
    }
}}

【讨论】:

  • 我想我已经尽力让它动态化,希望它可以解决你的目的。
  • 现在您可以将 parseJson 和 getArray 的返回类型更改为 String 并将它们添加到 ArrayList 中,您可以稍后对其进行迭代以获取所需的数据 :)
【解决方案3】:

1.) 创建一个适当类型的数组列表,在本例中为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);

代码:

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"));
}

注意:有时您可能会在values are not available in appropriate type or is there is no mapping key 时看到一些例外情况,所以在这些情况下,当您不确定是否存在价值时,请使用optStringoptIntoptBoolean等等,如果它不存在,它将简单地返回默认值,如果它是字符串类型,甚至尝试将值转换为 int,反之亦然,所以只要 根本没有 null 或 NumberFormat 异常缺少键或值

From docs

获取与键关联的可选字符串。它返回 如果没有这样的键,则为 defaultValue。

 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

进一步参考研究

【讨论】:

    【解决方案4】:

    非常感谢@Code 在另一个答案中。感谢您的代码,我可以读取任何 JSON 文件。现在,我正在尝试按级别组织所有元素,以便可以使用它们!

    我正在使用 Android 从 URL 读取 JSON,我唯一需要更改的是行

    Set<Object> set = jsonObject.keySet(); Iterator<Object> iterator = set.iterator();

    Iterator&lt;?&gt; 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);
                }
            }
        }
    }
    

    【讨论】:

      【解决方案5】:

      Java 中有许多可用的 JSON 库。

      最臭名昭著的是:Jackson、GSON、Genson、FastJson 和 org.json。

      在选择任何库时,通常应该考虑三件事:

      1. 性能
      2. 易于使用(代码易于编写且清晰易读)- 与功能相得益彰。
      3. 对于移动应用程序:依赖项/jar 大小

      特别是对于 JSON 库(以及任何序列化/反序列化库),数据绑定通常也很重要,因为它无需编写样板代码来打包/解包数据。

      对于 1,请参阅此基准:https://github.com/fabienrenaud/java-json-benchmark 我使用 JMH 比较了使用流和数据绑定 API 的序列化器和反序列化器的(jackson、gson、genson、fastjson、org.json、jsonp)性能。 对于 2,您可以在 Internet 上找到大量示例。上面的基准也可以用作示例的来源...

      快速了解基准: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);
          }
      }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 2014-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多