GSON:帮我解析一些未知的JSON数据

时间:2015-10-14 13:06:43

标签: java android json gson

您有JSON数据可以返回不同的数据,所以我正在编写deserialiser来解析它

所以基本上就是这个

{
  "data": {
    "errors": {
      "user": [
        "Invalid email, username or password. Please try again"
      ]
    }
  }
}

或者这个

{
  "errors": {
    "promotion": [
      "The code was invalid"
    ]
  }
}

我的目标是提取数组中的字符串,我不知道该字段将被调用。所有我知道的是它来自数据或错误或两者都在我内部我有一个未知的字段名称与消息数组。

所以我写了一个deserialiser

 @Override
    public APIErrorBody deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        String message = ""; /** The error message we are going to display */

        /** Backend inconsistency: Unsuccessful response from backend can come with node data -> or errors -> we must check what is there */
        JsonObject dataOrErrorsAsRoot = json.getAsJsonObject().get("data").getAsJsonObject();
        if(dataOrErrorsAsRoot == null){ //If we do not have data node then lets check for errors
            dataOrErrorsAsRoot = json.getAsJsonObject().get("errors").getAsJsonObject();
        }

        for (Map.Entry<String, JsonElement> entry : dataOrErrorsAsRoot.entrySet())
        {
            String key = entry.getKey();
            JsonElement element = entry.getValue();
            DebugUtils.Log(key + " " + element.toString());
            if(element.isJsonArray()){
                JsonArray jsonArray = element.getAsJsonArray();
                for(int i = 0; i < jsonArray.size(); i ++){
                    message +=  jsonArray.get(i).getAsString() + "\n";
                }
            }
        }


        APIErrorBody apiErrorBody = new APIErrorBody();
        apiErrorBody.setErrorMessageToDisplay(message);
        DebugUtils.Log("the final message is " + apiErrorBody.getErrorMessageToDisplay());
        return apiErrorBody;
    }

我遇到的问题是

  for (Map.Entry<String, JsonElement> entry : dataOrErrorsAsRoot.entrySet())
            {
                String key = entry.getKey();
                JsonElement element = entry.getValue();
                DebugUtils.Log(key + " " + element.toString());
                if(element.isJsonArray()){
                    JsonArray jsonArray = element.getAsJsonArray();
                    for(int i = 0; i < jsonArray.size(); i ++){
                        message +=  jsonArray.get(i).getAsString() + "\n";
                    }
                }
            }

所以问题是,即使在我调试时,它也不是JSON数组。 JsonElement&#39;元素中包含的值&#39;是

{"user":["Invalid email, username or password. Please try again"]}

这是一个数组

然而,我的调试器说这让我很困惑o_O

enter image description here

该元素是包含LinkedTreeMap的JSON对象 并且该映射具有JSON数组的值,我如何得到它:)

有人请帮忙,我快死了

3 个答案:

答案 0 :(得分:0)

好的调试器做对了,element.isJsonArray()提示&#34;用户&#34;确实是JsonArray。

你只需要一个LinkedTreeMap,它在String键和值之间进行映射。你给它一把钥匙并获得一个价值。价值可以是任何东西。如果是#34;用户&#34;键,值为JsonArray

答案 1 :(得分:0)

您可以使用此代码.lets表示String responseStr = new JSONObject(jsondat);

JSONObject response = new JSONObject(responseStr);
    if (response.has("data")) {
        JSONObject data = response.getJSONObject("data");
        JSONObject error = data.getJSONObject("errors");
        JSONArray users = error.getJSONArray("user");
    } else if (response.has("errors")) {
        JSONObject error = response.getJSONObject("errors");
        JSONArray promotion = error.getJSONArray("promotion");
    }

答案 2 :(得分:0)

我删除了旧答案,这是新答案。

我的错误,看我的后端可以发送数据然后错误或只是数据或只是错误作为根节点。我忘了访问数据然后错误

这是工作代码

@覆盖     public APIErrorBody反序列化(JsonElement json,Type typeOfT,JsonDeserializationContext context)抛出JsonParseException {         String message =“”; / **我们将显示错误消息* /

    /** Backend inconsistency: Unsuccessful response from backend can come with node data -> errors or just errors or just data we must check what is there :S */
    JsonObject dataOrErrorsAsRoot = json.getAsJsonObject();
    if(dataOrErrorsAsRoot.has("data")){ //Check if the first element is data
        dataOrErrorsAsRoot = json.getAsJsonObject().get("data").getAsJsonObject();
        if(dataOrErrorsAsRoot.has("errors")){ //Check if an errors element exists in the data element
            dataOrErrorsAsRoot = dataOrErrorsAsRoot.get("errors").getAsJsonObject();
        }
    }else{ //it must be errors only, but we should check in case a 503 happens and we try deserialise and empty body
        if(dataOrErrorsAsRoot.has("errors")){
            dataOrErrorsAsRoot = json.getAsJsonObject().get("errors").getAsJsonObject();
        }
    }

    if(dataOrErrorsAsRoot != null){
        for (Map.Entry<String, JsonElement> entry : dataOrErrorsAsRoot.entrySet()) //Lets loop through each field in the json object we got
        {
            JsonElement element = entry.getValue();
            if(element.isJsonArray()){ //if its an array get each string message and combine it
                JsonArray jsonArray = element.getAsJsonArray();
                for(int i = 0; i < jsonArray.size(); i++){
                    message +=  jsonArray.get(i).getAsString() + "\n";
                }
            }
        }
    }

    //Fail safe, if we got no message or no json just return some generic message
    if(TextUtils.isEmpty(message)){
        message = MyApplication.getInstance().getResources().getString(R.string.unknown_error);
    }

    APIErrorBody apiErrorBody = new APIErrorBody();
    apiErrorBody.setErrorMessageToDisplay(message);
    return apiErrorBody;
}