基于okhttp封装网络库 (3)

    xiaoxiao2021-03-25  118

    基于okhttp封装网络库 (3)

    前言:根据之前封装的库来写一个具体的请求豆瓣 api 的任务类!

    准备工作:

    通过 豆瓣 api,查看可知获取某个图书信息的 api 长这样。

    GET https://api.douban.com/v2/book/isbn/:name

    由第一点可知我们请求的 主机地址是 api.douban.com,具体图书 api则是 /v2/book/isbn/:name,请求方式是 GET,所以我们先来完成做以上三点。


    1. BookDetailTask

    //修改主机地址 public class HttpConfig { public static final String HOST = "https://api.douban.com"; } public class BookDetailTask extends GETRequest { private String mIsbn; public BookDetailTask(String isbn ) { super( ); mIsbn = isbn; } @Override public String getApi() { return "/v2/book/isbn/" + mIsbn; } @Override public int getHttpMethod() { return HttpMethod.GET; } @Override public Class getModelClass() { return BookBean.class; } } //GETRequest 让具体的任务类不用实现 BaseRequest 中 GET 请求方式中无用的接口。 public abstract class GETRequest extends BaseRequest { public MediaType getMediaType() { return null; } protected String getRequestString() { return null; } }
    但是我们通过 Postman 调试工具可以发现豆瓣返回的参数并不是一二级协议的格式。那怎么办呢?很简单,只要对我们类库进行一个简单的修改就可以,具体来讲就是手动构一个 HttpResponse出来,其实就是 okhttp 层接受到的 Response code 和 message 参数取出来。

    2. 构造 HttpResponse

    首先对 getResponse 方法进行修改。 private HttpResponse<T> getResponse(Response response) throws IOException { ResponseBody body = response.body(); //fastJson 中的 api Object data = JSON.parseObject(body.string(),getModelClass()); HttpResponse<T> httpResponse = new HttpResponse<T>(); httpResponse.data = (T) data; httpResponse.code = response.code(); httpResponse.message = response.message(); return httpResponse; } 其次对同步/异步模块修改 public HttpResponse<T> execute() throws IOException { Response response = this.mClient.newCall(buildRequest()).execute(); int code = response.code(); if (code == 200) { //正常请求 // ResponseBody body = response.body(); // return getResponse(body); return getResponse(response); } else { return null; } } //修改点在 onResponse 中将原来的 resonse.body() 注释掉,直接传入 response. public boolean enqueue(final HttpCallback<T> callback) { if (mCall == null) { mCall = mClient.newCall(buildRequest()); mCall.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { HttpResponse response = new HttpResponse(ResponseCode.NET_ERROR, ResourceHelper.getString(R.string.neterror), null); mDelivery.postResponse(callback, BaseRequest.this, response, e); } @Override public void onResponse(Call call, Response response) throws IOException { HttpResponse<T> httpResponse = null; try { // httpResponse = getResponse(response.body()); httpResponse = getResponse(response); mDelivery.postResponse(callback, BaseRequest.this, httpResponse, null); } catch (IOException e) { httpResponse = new HttpResponse(ResponseCode.NET_ERROR, ResourceHelper.getString(R.string.neterror), null); mDelivery.postResponse(callback, BaseRequest.this, httpResponse, e); } catch (JSONException e) { httpResponse = new HttpResponse(ResponseCode.JSON_ERROR, ResourceHelper.getString(R.string.jsonparseerror), null); mDelivery.postResponse(callback, BaseRequest.this, httpResponse, e); } } }); } else { if (mCall.isCanceled() || mCall.isExecuted()) { Log.e("TAG", "cancel executed"); } } return true; }

    3.使用 BookDetailTask 完成调用。

    // 封装这个 Action 类的目的是避免在业务层过多的调用 BookDetailTask 造成代码混乱,避免冗余同时也与业务层开发解耦。 public class BookDetailAction { //只要调用者传入 IGetBookCB 回调接口就可以收到消息。 public static void getBookkDetail(String result, final IGetBookCB cb ) { final BookDetailTask task = new BookDetailTask(result); task.enqueue(new HttpCallback() { @Override public void onResponse(BaseRequest request, Object data) { if (cb != null) { cb.onConnectSuccess(data); } } @Override public void onFailure(BaseRequest request, Exception e, int code, String message) { if (cb !=null){ cb.onConnectFailed(code,message); } } }); } public interface IGetBookCB { void onConnectSuccess(Object o); void onConnectFailed(int code ,String message); } }

    完整例子: https://github.com/hexianzhi/MyOkHttpDemo

    转载请注明原文地址: https://ju.6miu.com/read-5072.html

    最新回复(0)