代码之家  ›  专栏  ›  技术社区  ›  Hunt

概括处理所有web服务调用的响应和错误的方法

  •  4
  • Hunt  · 技术社区  · 8 年前

    我正在尝试创建通用方法来处理以下问题

    1. 处理HTTP错误和自定义错误

    为此,我编写了以下代码并打包了回调来处理响应 ResponseCallback 错误和错误 ErrorCallback

        Request request = new Request();
        request.setAccess_token("d80fa6bd6f78cc704104d61146c599bc94b82ca225349ee68762fc6c70d2dcf0");
        request.setStart_date("2018-06-01T00:00:00");
        Flowable<Response> fitnessFlowable = new WebRequest()
                .getRemoteClient()
                .create(FitnessApi.class)
                .getFitnessData("5b238abb4d3590001d9b94a8",request.toMap());
    
          fitnessFlowable.subscribeOn(Schedulers.io())
                .takeUntil(response->response.getSummary().getNext()!=null)
                .doOnNext(new ResponseCallback())
                .doOnError(new ErrorCallback<Throwable>())
                .subscribe();
    

    响应回调

    public  class ResponseCallback<T extends Response> implements Consumer<Response> {
    
    
        @Override
        public void accept(Response response) throws Exception {
            if(response ==null || response.getFitness() == null || response.getFitness().isEmpty()) {
    
    
                new Exception("NUll response");
    
            }
    
            RxBus.getInstance().send(response.getFitness());
           Log.e("Data","accept");
            try(Realm r = Realm.getDefaultInstance()) {
                r.executeTransaction((realm) -> {
                    realm.copyToRealmOrUpdate(response.getFitness());
                });
            }
        }
    }
    

    public class ErrorCallback <T extends Throwable> implements Consumer<Throwable> {
    
        public static final String TAG = "ErrorCallback";
        @Override
        public void accept(Throwable e) throws Exception {
    
            if (e instanceof HttpException) {
                ResponseBody body = ((HttpException) e).response().errorBody();
                try {
                    Response response=  LoganSquare.parse(body.byteStream(),Response.class);
    
                    if(response.getErrors() !=null)
                        if(response.getErrors().size() > 0)
                          Log.e(TAG , response.getErrors().get(0).getErrors() );
    
                } catch (IOException t) {
                    t.printStackTrace();
                }
    
            } else if (e instanceof SocketTimeoutException) {
    
                Log.e(TAG , e.getMessage() );
    
            }else if (e instanceof IOException) {
    
                Log.e(TAG , e.getMessage() );
            }else{
                Log.e(TAG , e.getMessage() );
            }
        }
    }
    

    我想解决两个问题

    1. 为了处理响应和错误,我需要进行两次单独的回调。有没有其他方法可以让我在回调中处理响应和错误,而不是创建两个单独的

    2. 我什么时候应该在上面的代码中处理订阅,因为你可以在我的代码中看到我的订阅正在讨价还价。

    我已经裁判过了 this link 设计归纳法。

    1 回复  |  直到 8 年前
        1
  •  1
  •   jesses.co.tt    8 年前

    为了处理响应和错误,我需要进行两次单独的回调。是 有没有其他方法可以处理回调中的响应和错误 而不是创造两个独立的

    在干净的体系结构方法中,您的web服务将被定义为一个远程数据源(可能遵循“数据源”协议)。远程数据源应该以类格式序列化它的结果-如果您能够使用Kotlin,那么 sealed class

    /**
     * The return state from the Data Layer
     */
    sealed class ServiceResult {
    
        data class Success(val list: List<MySerializedObject>) : ServiceResult()
    
        data class Error(val reason: Throwable?) : ServiceResult()
    }
    

    最后,你可以从一个单独的层切换到另一个层,这样你就可以把数据从一个单独的层切换到另一个层,在这里你可以这样做:

      when (result) {
                        is ServiceResult.Success -> {
                            serializeToViewModel(result) // VM to the Adapter
                        }
                        is ServiceResult.Error -> result.reason?.let {
                            PartialViewState.Error(it) // Can be rendered immediately
                        } 
                    }
    

    然后,演示者可以对视图调用呈现方法,如下所示:

                ... subscribeOn() etc
                .subscribe({ view?.render(it) }, { view?.render(ViewState(error = it)) })
    

    然后,视图的render方法可以在要呈现的视图状态、要显示的错误消息等之间进行少量的逻辑切换。

    仅供参考,我正在使用的架构非常依赖 MVI by Hans Dorfmann ... 我强烈推荐。