基于okhttp封装网络库 (3)

来源:互联网 发布:移动应用测试 知乎 编辑:程序博客网 时间:2024/06/06 01:31

基于okhttp封装网络库 (3)

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

准备工作:

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

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

  2. 由第一点可知我们请求的 主机地址是 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

  1. 首先对 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;    }
  1. 其次对同步/异步模块修改
 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

0 0
原创粉丝点击