是否可以在不知道其密钥的情况下从一组JSON对象中获取值?

时间:2015-07-05 02:55:07

标签: java json

我正在开发一个使用JSON与Web API对话的应用。在其中一个错误案例中,API会向我发送一个“错误包”,看起来非常像这样:

{
    "status_code": " 400",
    "message": " Bad Request",
    "errors": [
        { " error1": "errorMessage1" },
        { " error2": "errorMessage2" },
        { " error3": "errorMessage3" },
        ...
        { " errorN": "errorMessageN" }
    ]
}

对我而言,JSON中最重要的是errorMessage - 因为我需要它们作为我随后向用户显示的错误对话框的内容。

但在实际场景中,那些error s将拥有彼此不同的键(例如PasswordErrorObjectXIsNeeded等等)并且说实话,我无法真实地预测可能存在的error。添加可能在将来添加的新错误的可能性。

我之前想到的是迭代errors JSON对象数组并获取它们的值。就像你在处理Map时所做的那样。但我似乎无法按照我喜欢的方式去做。

作为一个例子,这就是我的想法:

StringBuilder errorMessages = new StringBuilder();
JSONArray errors = returnJson.getJsonArray("errors");
for(JSONObject error : errors) {
    errorMessages.append(error.getValue());
}

这种事情可以吗?怎么样?

修改:根据要求,我会列出问题的详细信息:

  • 我正在使用Android提供的默认JSON库(或者是Java?),结果证明是org.json
  • API由我公司提供,不太可能改变。许多系统已经依赖它。

3 个答案:

答案 0 :(得分:1)

在与JSON相关的问题中,您应该明确说明您使用的是哪个JSON库,因为它们中有很多,类似JSONArray的类名在那里类似。

如果您正在使用org.json API(旧的和过时的,因此不建议使用),那么有一个keys方法返回一个obejct键的迭代器:

Iterator it = errors.keys();
while(it.hasNext()) {
    String key = it.next().toString();
    errorMessages.append(errors.get(key));
}

答案 1 :(得分:1)

这取决于您用来操作JSON文档的API。如果您使用的是www.json.org定义的API,您可以iterate over the keys或实际生成您希望的数组:JSONObject.toJSONArray(...)

答案 2 :(得分:0)

好吧,有点儿。你只会在不知道密钥的情况下到目前为止,但是一点正则表达式可以帮到这里。

请注意,我不会鼓励这种用法;如果您的结构强制要求您不关心密钥,请重新排列JSON的结构,以便您只返回值。

理想的结构是这样的:

{
    "status_code": " 400",
    "message": " Bad Request",
    "errors": ["errorMessage1", "errorMessage2","errorMessage3","errorMessageN"]
}

那说:

  • 我正在使用org.json packages
  • 我精心设计了一个正则表达式来对我关心的JSON对象的值部分进行分组。

    .*?:\"(.*?)\".*?
    

Regular expression visualization

Debuggex Demo

  • 我使用的是LinkedHashSet,而不是StringBuilder
String json = "{\n" +
                      "    \"status_code\": \" 400\",\n" +
                      "    \"message\": \" Bad Request\",\n" +
                      "    \"errors\": [\n" +
                      "        { \" error1\": \"errorMessage1\" },\n" +
                      "        { \" error2\": \"errorMessage2\" },\n" +
                      "        { \" error3\": \"errorMessage3\" },\n" +
                      "        { \" errorN\": \"errorMessageN\" }\n" +
                      "    ]\n" +
                      "}";

JSONObject returnJson = new JSONObject(json);
JSONArray errors = returnJson.getJSONArray("errors");
Pattern pattern = Pattern.compile(".*?:\"(.*?)\".*?");
Set<String> errorSet = new LinkedHashSet<>();
for(int i = 0; i < errors.length(); i++) {
    Matcher matcher = pattern.matcher(errors.get(i).toString());
    if(matcher.matches()) {
        errorSet.add(matcher.group(1));
    }
}
System.out.println(errorSet);