背景
之前项目中有使用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();
}
总结
这样处理后,即支持了请求权限系统,又包装处理了权限异常的返回,整个使用起来是比较方便的。现在很多框架其实都提供了非常好用的扩展功能,开发中如果能多从全局出发考虑,合理利用框架的扩展功能,项目的架构也会更清晰简洁和方便维护。
感谢阅读。
网友评论