基于okhttp封装网络库 (3)

基于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 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 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 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

你可能感兴趣的:(Android)