Retrofit使用中拦截请求接入权限系统

2020-04-21  本文已影响0人  西5d

背景

之前项目中有使用retrofit来封装http请求,Retrofit是一个对RESTful的HTTP网络请求框架的封装,网络请求是由OkHttp负责的。遇到项目中有添加内部权限框架,需要首先请求权限系统,而且如果权限异常,返回值结构是和业务系统不一致的。如果每个接口都去处理,十分的繁琐,也不利于后期的维护。于是,考虑有什么简洁的方法来实现。

方案设计

首先,明确目的:一要先请求权限系统获取token,二要处理异常的返回。既然底层http支持是Okhttp处理的,所以考虑retrofit中的拦截器来实现。构造一个拦截器,先去权限系统请求token,再去执行请求,如果权限异常,再封装请求返回,统一成和业务系统一致的返回结构,但写入具体的报错信息,代码如下。

代码

    public static OkHttpClient.Builder getClientBuilderIntercepted() {
        OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
        final int SUCCESS_CODE = 200;
        final MediaType MEDIA_TYPE = MediaType.parse("application/json;charset=UTF-8");

        Interceptor interceptor = chain -> {
            Request request = chain.request();

            Request newRequest = builderAuthRequest(request);

            Response response = chain.proceed(newRequest);
            if (null != response) {
                if (response.code() == HttpStatus.ORDINAL_400_Bad_Request) {
                    String body = response.body() == null ? "" : response.body().string();
                    AuthResp AuthResp = new Gson().fromJson(body, AuthResp.class);
                    BaseResp resp = BaseResp.fail("未知异常");
                    if (null != AuthResp) {
                        String msg =
                                String.format("auth resp -> code:%s,desc:%s", AuthResp.getCode(), AuthResp.getDescription());
                        resp.setMsg(msg);
                        response =
                                response.newBuilder().code(SUCCESS_CODE).body(ResponseBody.create(MEDIA_TYPE, new Gson().toJson(resp))).build();
                    } else {
                        response =
                                response.newBuilder().code(SUCCESS_CODE).body(ResponseBody.create(MEDIA_TYPE, new Gson().toJson(resp))).build();
                    }
                    LOG.error("resp origin:{}", body);
                }
            }
            return response;
        };

        httpClientBuilder.addNetworkInterceptor(interceptor);
        httpClientBuilder.addNetworkInterceptor(new LoggingInterceptor());
        return httpClientBuilder;
    }

    /**
     * 权限控制请求
     * @param oldRequest
     * @return
     */
    private static Request builderAuthRequest(Request oldRequest) {
        HttpUrl.Builder oldRequestBuilder = oldRequest.url().newBuilder();
        try {
            //内部权限类
            TokenInfo info = getToken();
            HttpUrl newUrl = oldRequestBuilder
                            .addQueryParameter(AuthConstants.APP_ID, getAppId())
                            .addQueryParameter(AuthConstants.TOKEN, info.getToken())
                            .build();

            return oldRequest.newBuilder().url(newUrl).build();
        } catch (Exception e) {
            LOG.error("build auth query parameter url error.", e);
        }
        return oldRequest;
    }
    
    /**
    * 创建retrofit
*/
    public static Retrofit getRetrofitInstance(String url, OkHttpClient.Builder builder, Converter.Factory convertFactory, CallAdapter.Factory callAdapterFactory) {
        Retrofit.Builder retrofitBuilder = new Retrofit.Builder().baseUrl(url).client(builder.build());
        if (null != convertFactory) {
            retrofitBuilder.addConverterFactory(convertFactory);
        }
        if (null != callAdapterFactory) {
            retrofitBuilder.addCallAdapterFactory(callAdapterFactory);
        }
        return retrofitBuilder.build();
    }

总结

这样处理后,即支持了请求权限系统,又包装处理了权限异常的返回,整个使用起来是比较方便的。现在很多框架其实都提供了非常好用的扩展功能,开发中如果能多从全局出发考虑,合理利用框架的扩展功能,项目的架构也会更清晰简洁和方便维护。
感谢阅读。

上一篇下一篇

猜你喜欢

热点阅读