基于retrofit网络请求token过期的处理逻辑
2017-08-31 15:42
381 查看
手机调用接口,关键数据请求需要验证token,token设置按照一定周期就过期。验证token需要判断token是否过期,如果过期就需要后台调用登陆接口获取新的token,并且用新的token替换原来的token,在后台继续完成原来未完成的请求。
经过尝试,基本完成实现与优化。
一、首先贴出接口代码,采用SpringBoot编写的简单接口:
二、用Java做测试,用到的工具类
三、同步登陆
四、处理问题主要在拦截器内
五、测试代码
六、运行结果的截图:
经过尝试,基本完成实现与优化。
一、首先贴出接口代码,采用SpringBoot编写的简单接口:
@RestController public class UserController { private static String newToken="ZTAwNjIyOGQtZmU1Zi00NmNiLWJjNTgtMTY1MmE4OTI4OTkwCHRISCHEN"; /** * 获取用户信息,验证token * @param body * @return */ @PostMapping("/getUserInfo") public String getUserInfo(@RequestBody NetRequest body) { String token=body.protocol.token; if (newToken.equals(token)){ return GsonUtils.toJson(new NetResult<>(0,"getUserInfo success",new UserModel("kalychen","man",45))); }else { return GsonUtils.toJson(new NetResult<>(999,"Token time out","")); } } /** * 登录,获得新的token * @param body * @return */ @PostMapping("/login") public String login(@RequestBody NetRequest body) { //此处省略对请求参数的验证 return GsonUtils.toJson(new NetResult<>(0,"give you a new token",newToken)); } }
二、用Java做测试,用到的工具类
public class RequestUtils { /** * 替换RequestBody中NetRequest自定义协议内的Token * * @param body * @param newToken * @return */ public static RequestBody replaceToken(RequestBody body, String newToken) { NetRequest requestBody = getRequestBody(body); requestBody.protocol.token = newToken; return RequestBody.create(body.contentType(), JsonUtils.objToJson(requestBody)); } /** * 获得NetRequest类型的requestBody,便于取出其中的协议信息 * * @param body * @return */ public static NetRequest getRequestBody(RequestBody body) { return JsonUtils.jsonToObj(getRequestBodyJson(body), NetRequest.class); } /** * 获得request中body的json字符串,便于打印 * * @param body * @return * @throws IOException */ public static String getRequestBodyJson(RequestBody body) { Buffer buffer = new Buffer(); try { body.writeTo(buffer); Charset charset = Charset.forName("UTF-8"); MediaType mediaType = body.contentType(); if (mediaType != null) { charset = mediaType.charset(StandardCharsets.UTF_8); } return buffer.readString(charset); } catch (IOException e) { e.printStackTrace(); } return null; } /** * token过期,重新请求 * @param oldRequest * @return * @throws IOException */ public static Request reRequest(Request oldRequest) throws IOException { //1.登录接口,拿到新的Token NetResult<String> netResult = (NetResult) TestApi.loginSync("13333333333", "123456").body();//同步登录 String token=netResult.data; //2.替换掉Token RequestBody oldRequestBody = oldRequest.body();//获取旧的requestBody RequestBody requestBody = replaceToken(oldRequestBody, token);//替换Token //3.重新构建 return new Request.Builder().post(requestBody).url(oldRequest.url()).build();//重新构建request }
三、同步登陆
public class TestApi extends NetApi implements UrlConsts { private static TestService service = NetClient.getRetrofit(TEST_BASE_URL).create(TestService.class); public static void getUserInfo(NetCallback<UserBean> callback) { Map<String, Object> map = new HashMap<>(); Call call = service.getUserInfo(postRequestBody(map)); call.enqueue(callback); NetManager.addRequest(call); } public static void login(String phoneNumber, String password, NetCallback<String> callback) { Map<String, Object> map = new HashMap<>(); map.put("phoneNumber", phoneNumber); map.put("password", password); Call call = service.login(postRequestBody(map)); call.enqueue(callback); NetManager.addRequest(call); } /** * 同步请求 * * @param phoneNumber * @param password */ public static Response loginSync(String phoneNumber, String password) throws IOException { Map<String, Object> map = new HashMap<>(); map.put("phoneNumber", phoneNumber); map.put("password", password); Call call = service.login(postRequestBody(map)); return call.execute(); } }
四、处理问题主要在拦截器内
public class NetInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Response response = chain.proceed(request);//执行请求 String responseBodyStr = handResponse(response);//获得处理后的数据字符串 if (tokenException(responseBodyStr)) {//判断是否token过期 responseBodyStr = handResponse(chain.proceed(RequestUtils.reRequest(request))); } return response.newBuilder() .body(ResponseBody.create(response.body().contentType(), responseBodyStr)) .build(); } /** * 判断是否被告知Token过期 * * @param responseBodyStr * @return */ private boolean tokenException(String responseBodyStr) { NetResult netResult = JsonUtils.jsonToObj(responseBodyStr, NetResult.class); return netResult.code == 999; } /** * 处理response * * @param response * @return * @throws IOException */ private String handResponse(Response response) throws IOException { String passWord = "chrischen";//加密解密专用密码 ResponseBody responseBody = response.body(); String responseBodyStr = responseBody.string(); String requestUrl = response.request().url().url().toString();//请求路径 MsgUtils.show("MobileAPI:" + requestUrl + " 返回数据==>" + responseBodyStr); return responseBodyStr; } }
五、测试代码
private static void test() throws Exception { NetCallback<UserBean> callback = new NetCallback<UserBean>() { @Override protected void onComplete(NetResponse<UserBean> netResponse) { } }; TestApi.getUserInfo(callback); }
六、运行结果的截图:
相关文章推荐
- (二)最流行的网络请求框架Rxjava2+Retrofit之Token处理
- 基于Retrofit扩展一个统一处理网络请求的CallBack
- 基于Restful架构规范的Android的网络请求框架Retrofit
- 封装网络请求库,统一处理通用异常 (基于volley网络请求库)
- RxJava Retrofit2 网络请求,返回数据格式统一的数据报文处理方法
- Retrofit+RxJava处理网络请求
- 使用Retrofit和Okhttp实现网络缓存。无网读缓存,有网根据过期时间重新请求
- RxJava Retrofit2 网络请求,返回数据格式统一的数据报文处理方法
- Renovace :一款基于Retrofit & RxJava 实现简单易用的网络请求框架
- 使用Retrofit和Okhttp实现网络缓存。无网读缓存,有网根据过期时间重新请求
- Retrofit请求数据对错误以及网络异常的处理
- Android使用Retrofit2.0和RxJava2.0处理网络请求
- 转-封装网络请求库,统一处理通用异常 (基于volley网络请求库)
- 基于Retrofit+RxJava的Android分层网络请求框架
- Retrofit请求数据对错误以及网络异常的处理
- 基于Retrofit+RxJava的Android分层网络请求框架
- Android基于Retrofit2.0和RXJava2.0 的HTTPS网络请求搭建
- Retrofit请求数据对错误以及网络异常的处理
- 使用MVP+Retrofit+RxJava实现的的Android Demo (下)使用Retrofit+RxJava处理网络请求
- RxJava结合Retrofit对网络请求结果的统一处理