【问题标题】:How to Handle Two Different Response in Retrofit如何在改造中处理两种不同的响应
【发布时间】:2018-12-16 16:48:42
【问题描述】:

我跟随 this 使用 Retrofit2 发布数据

我使用JSON POJO 来解析我的 POST 和 GET 文件

所以这里如果记录中的数据在那里我会得到这种响应

{
"status": "200",
"response": [{
        "cnt_id": "201",
        "phn_no": "3251151515",
        "dat_cnt": "Reset Password request Said to Mail"
    },
    {
        "cnt_id": "209",
        "phn_no": "555465484684",
        "dat_cnt": "Hi DEMO User , Congratulations! Your account has been created successfully."
    },
    {
        "cnt_id": "210",
        "phn_no": "4774748",
        "dat_cnt": "Hi XYZ , Congratulations! Your account has been created successfully."
    }
]
}

如果没有数据我会得到

{"status":"204","response":{"msg":"No Content"}}
{"status":"400","response":{"msg":"BadRequest"}}
{"status":"401","response":{"msg":"Unauthorized User"}}

所以在这里我可以解析状态为 200 的数据,但是当状态不等于 200 时我想处理它们

我试过了

   status = response.body().getStatus();
   if(status.equals("200")) {
      List<Response> resList =  response.body(). getResponse();

            for(int i = 0; i<resList.size(); i++)
            {.
             .
              ..
             .
            }
        }

        else {
             //not Implemented
             }

现在我应该写什么否则我在 POJO 中使用了不等于 200 的响应数据,但我要求列表

更新

com.example.Example.java

public class Example {
    @SerializedName("status") @Expose private String status;
    @SerializedName("response") @Expose private List<Response> response = null;
}        

com.example.Response.java

public class Response {
    @SerializedName("cnt_id") @Expose private String cntId;
    @SerializedName("phn_no") @Expose private String phnNo;
    @SerializedName("dat_cnt") @Expose private String datCnt;
}

【问题讨论】:

标签: android json retrofit2 jsonschema2pojo


【解决方案1】:
public class Example {
    @SerializedName("status") @Expose private String status;
    @SerializedName("response") @Expose private Object response = null;
}

public class Response {
    @SerializedName("cnt_id") @Expose private String cntId;
    @SerializedName("phn_no") @Expose private String phnNo;
    @SerializedName("dat_cnt") @Expose private String datCnt;
}

public class ResponseError{
    @SerializedName("msg") @Expose private String msg;
}

你的回调方法应该是这样的

new Callback<Example>() {
            @Override
            public void onResponse(Call<Example> call, Response<Example> response) {
                if(response.isSuccessful()){
                    Example example = response.body();
                    Gson gson = new GsonBuilder().create();
                    if(example.status.equals("200")) {
                        TypeToken<List<Response>> responseTypeToken = new TypeToken<List<Response>>() {};
                        List<Response> responseList = gson.fromJson(gson.toJson(example.getResponse()), responseTypeToken.getType());
                    } else {
                        //If for everyOther Status the response is Object of ResponseError which contains msg.
                        ResponseError responseError = gson.fromJson(gson.toJson(example.getResponse()), ResponseError.class);
                    }
                }
            }

            @Override
            public void onFailure(Call<Example> call, Throwable t) {
                //Failure message
            }
        }

【讨论】:

  • 我知道如何在示例类中使用这个 ResponseError
  • 有什么问题
  • 你已经添加了这一行 @SerializedName("response") @Expose private String response = null;很好..我需要为 ResponseError 添加另一个吗?
  • 如果你有自己的,那也没关系。不要创建一个。只用那个。如果不是创建。否则,您将无法解析来自 Gson 的响应。
  • 其实它的调用列表是什么。public List&lt;Response&gt; getResponse() { return response; } 对于非数组列表我需要添加响应错误?
【解决方案2】:

您可以在 Retrofit2 的帮助下通过获取 errorBody() 来实现此目的。

创建一个名为 RestErrorResponse.java 的 POJO 模型类,用于处理此响应。

{"status":"401","re​​sponse":{"msg":"未授权用户"}}

并遵循以下信息:

 if (response.isSuccessful()) {

        // Your Success response. 

 } else {

        // Your failure response. This will handles 400, 401, 500 etc. failure response code


         Gson gson = new Gson();
         RestErrorResponse errorResponse = gson.fromJson(response.errorBody().charStream(), RestErrorResponse.class);
                    if (errorResponse.getStatus() == 400) {
                        //DO Error Code specific handling

                        Global.showOkAlertWithMessage(YourClassName.this,
                                getString(R.string.app_name),
                                strError);

                    } else {
                        //DO GENERAL Error Code Specific handling
                    }
                }

我用这种方法处理了所有的失败响应。希望这也可以帮助你。

【讨论】:

  • 实际上我正在使用示例和响应类我应该在哪里更新这个{"status":"401","response":{"msg":"Unauthorized User"}} 以及其他应该是什么......?
  • @Don'tBenegative 你需要创建单独的类来处理这个错误响应。
  • 在上面代码的else部分打印response.errorBody().charStream()的日志。
  • 你是在正确的方式。将“RestErrorResponse”替换为您的“示例”类。然后通过 errorResponse.getResponse().getMsg() 获取您的错误消息。明白了吗??
  • 我需要再创建两个类吗?例如 =RestErrorResponse 和 Response=R​​esponse2?
【解决方案3】:
class Response<T> {
        private String status;
        private T response;

        private boolean isSuccess() {
            return status.equals("200");
        }
    }

    class ListData {
        private String cnt_id;
        private String phn_no;
        private String dat_cnt;
    }

    class Error {
        private String msg;
    }

    public class MainResponse {
        @SerializedName("Error")
        private Error error;
        @SerializedName("AuthenticateUserResponse")
        private List<ListData> listData;
    }

@POST("listData")
Call<Response<MainResponse>> listData();

【讨论】:

  • hi user@user3235116 一旦检查我的更新,你能建议我哪里需要改变
  • 感谢您的回答...您能在我的代码中给我建议吗...?
【解决方案4】:

你可以使用不同的 pojo 类来处理错误消息

status = response.body().getStatus();
if(status.equals("200")) {
    ResponseSuccess res =  response.body();
    for(int i = 0; i < res.response.size(); i++){
        Log.d("TAG", "Phone no. " + res.response.get(i).phn_no);
    }
} else {
    Converter<ResponseBody, ResponseError> converter = getRetrofitInstance().responseBodyConverter(ResponseError.class, new Annotation[0]);
    ResponseError error;
    try {
        error = converter.convert(response.errorBody());
        Log.e("TAG", error.response.msg);
    } catch (IOException e) {
        error = new ResponseError();
    }
}

成功的pojo类

public class ResponseSuccess {
    public String status;
    public List<Response> response;
    public class Response{
        public String cnt_id;
        public String phn_no;
        public String dat_cnt;
    }
}

错误 pojo 类

public class ResponseError {
    public String status;
    public Response response;
    public class Response{
        public String msg;
    }
}

【讨论】:

  • 实际上在响应类之前我有状态?,,所以我有两个类pastebin.com/raw/fQMFAUXW 现在我需要创建第三类?我试图在示例或响应类中添加你的代码我遇到错误
  • 您可以像我定义的那样为成功和错误创建单个类,请检查
  • 嗨@VinayRathod 现在我有 3 个 calsses...MainResponse,ResponseSuccess,ResponseError 但是在主响应中我应该在主响应中定义什么...我已经在调用pastebin.com/raw/xB0Y7nmp 中定义了响应列表。所以如果没有回应我该怎么办
  • 你不必创建MainResponse,因为它在ResponseSuccess类中被覆盖
【解决方案5】:

因此,在您的情况下,可能会将响应标记类型设为String/List&lt;Response&gt;。所以你将响应标签类型声明为Object

@SerializedName("response") @Expose public Object response;

并在改造后的onResponse方法中编写代码sn-p

if (response.body().response!=null &&  response.body().response instanceof Collection<?>) {
            //if you find response type is collection then convert to json then json to real collection object
            String responseStr = new Gson().toJson(data.diagnosis.provisionalDiagnosis);
            Type type=new TypeToken<List<Response>>(){}.getType();
            List<Response> responseList=new Gson().fromJson(responseStr,type);
            if(responseList.size() > 0){
                binding.phoneTv.setText(responseList.get(0).phnNo);
            }
        }

我发现这是处理具有多种类型的单个标签的简单方法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-28
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    • 2018-05-26
    • 1970-01-01
    相关资源
    最近更新 更多