简体   繁体   English

如何使用可能的响应类型来使用Retrofit响应?

[英]How to consume Retrofit response with possible response types?

I am introducing Retrofit 2 to one of our new projects. 我正在向我们的一个新项目介绍Retrofit 2。 I am having a particular issue when I consume a web service response using Retrofit. 当我使用Retrofit使用Web服务响应时,我遇到了一个特殊问题。

I am using retrofit 2.3.0, and the retrofit gson converter 2.3.0. 我正在使用改装2.3.0,以及改装gson转换器2.3.0。

My problem is as follows. 我的问题如下。 The web service API that I am consuming will respond with 2 possible Response Models when a request is 200-OK. 我正在使用的Web服务API将在请求为200-OK时响应2个可能的响应模型。

  1. Web service handled request fine and responds with expected response model defined in response callback. Web服务处理了请求,并使用响应回调中定义的预期响应模型进行响应。
  2. Web service fails to handle request and sends back an exception model as the response. Web服务无法处理请求并将异常模型作为响应发回。 Still sending a 200-OK... 仍然发送200-OK ......

Believe me, I know the problem here... The web service should not be responding on success if a web service exception was thrown... it should be responding with a 500-5xx. 相信我,我知道这里的问题...如果抛出Web服务异常,Web服务不应该响应成功...它应该响应500-5xx。 All of this would become much easier. 所有这一切都会变得容易多了。 Anyways, I need to conform to this logic. 无论如何,我需要遵循这个逻辑。

This is what I have and it is working however, I think there is a better approach to this and I don't want to write the same code over and over which performs the casts operations every time I consume a response. 这就是我所拥有的并且它正在工作,但我认为有一个更好的方法,我不想一遍又一遍地编写相同的代码,每次我使用响应时执行强制转换操作。 However, I am not sure which is the correct approach here. 但是,我不确定这是哪种方法。

call.enqueue(new Callback<JsonObject>() {

     @Override
     public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
        //cast operation
        Gson gson = new Gson();
        ServiceException exception = gson.fromJson(response.body(), ServiceException.class);
        if(response.isSuccessful()){
             if(null != exception.getCode()){
                 //handleException(exception);
             }else{
                 //User authenticated successfully.

                 //cast operation
                 LoginResponseModel loginResponseModel = gson.fromJson(response.body(), LoginResponseModel.class);
                 //Perform actions with login response model.

                 //Launch dashboard if everything is ok.
                 Intent startDashboard = new Intent(LoginActivity.this, DashboardActivity.class);
                 startActivity(startDashboard);
             }
         }
     }

     @Override
     public void onFailure(Call<JsonObject> call, Throwable t) {
         Log.e(TAG, t.getMessage());
     }

});

This is my desired goal: 这是我理想的目标:

call.enqueue(new Callback<LoginResponseModel, ServiceException>() {

        @Override
        public void onResponse(Call<LoginResponseModel, ServiceException> call, Response<LoginResponseModel, ServiceException> response) {
               if(response instanceof ServiceException){
                   handleException(response);
               }else if(response instanceof LoginResponseModel){
                   //User authenticated successfully.
                   LoginResponseModel loginResponseModel = gson.fromJson(response.body(), LoginResponseModel.class);
                   //Perform actions with login response model.

                   //Launch dashboard if everything is ok.
                   Intent startDashboard = new Intent(LoginActivity.this, DashboardActivity.class);
                   startActivity(startDashboard);

                }
            }
        }

        @Override
        public void onFailure(Call<LoginResponseModel, ServiceException> call, Throwable t) {
            Log.e(TAG, t.getMessage());
        }

    });

Do I need a custom Callback implementation to achieve my goal? 我是否需要自定义Callback实现来实现我的目标? Do I need a custom response interceptor? 我需要自定义响应拦截器吗? Do I need a custom response converter? 我需要自定义响应转换器吗? Any ideas of a better approach? 任何更好的方法的想法?

I am a little new to Retrofit and I haven't found much information about a scenario like this. 我对Retrofit有点新,我没有找到关于这种情况的很多信息。

Hm what about use try catch and handle gson JsonSyntaxException ? 嗯,使用try catch和处理gson JsonSyntaxException怎么JsonSyntaxException Something like this: 像这样的东西:

call.enqueue(new Callback<JsonObject>() {
        @Override
        public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
            Gson gson = new Gson();
            try {
                ServiceException exception = gson.fromJson(response.body(), ServiceException.class);
                //handleException(exception);
            } catch (JsonSyntaxException e) {
                // Incorrect class, deserialize using LoginResponseModel 
                LoginResponseModel loginResponseModel = gson.fromJson(response.body(), LoginResponseModel.class);
                //User authenticated successfully.
                //Launch dashboard if everything is ok.
                Intent startDashboard = new Intent(LoginActivity.this, DashboardActivity.class);
                startActivity(startDashboard);
            }
        }

        @Override
        public void onFailure(Call<JsonObject> call, Throwable t) {
            Log.e(TAG, t.getMessage());
        }
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM