其实okhttp3更多的我也是先看别人的博客和官方的文档信息后才开始用,而且网上关于这样流行的框架的知识也是不胜枚举,关于该框架的封装主要还是看了慕课网上视频链接相关的视频,然后在他封装的基础上进行改进的,其实okhttp已经非常好用和简洁了,但是还是有些参数需要进行配置,并且这个封装代码量也不是很多,比较好容易进行理解,同时更推荐大家直接将代码copy到项目中,然后根据自己的需求进行一个动态的修改,这样的封装就很DIY了。
相关的类大概也就这些。下面来一个一个进行讲解。
1.首先来看最重要的配置类:CommonOkHttpClient
代码:
public class CommonOkHttpClient
{
private static final int TIME_OUT = 30;
private static OkHttpClient mOkHttpClient;
// private static CommonOkHttpClient mClient = null;
//静态代码块吃初始化Client相关的信息
static
{
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder.hostnameVerifier(new HostnameVerifier()
{
@Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
});
okHttpClientBuilder.cookieJar(new SimpleCookieJar());
okHttpClientBuilder.connectTimeout(TIME_OUT, TimeUnit.SECONDS);
okHttpClientBuilder.readTimeout(TIME_OUT, TimeUnit.SECONDS);
okHttpClientBuilder.writeTimeout(TIME_OUT, TimeUnit.SECONDS);
okHttpClientBuilder.followRedirects(true);
/**
* trust all the https point
*/
okHttpClientBuilder.sslSocketFactory(HttpsUtils.getSslSocketFactory());
mOkHttpClient = okHttpClientBuilder.build();
}
/**
* 指定cilent信任指定证书
*
* @param certificates
*/
public static void setCertificates(InputStream... certificates)
{
mOkHttpClient.newBuilder().sslSocketFactory(HttpsUtils.getSslSocketFactory(certificates, null, null)).build();
}
/**
* 指定client信任所有证书
*/
public static void setCertificates()
{
mOkHttpClient.newBuilder().sslSocketFactory(HttpsUtils.getSslSocketFactory());
}
/**
* 通过构造好的Request,Callback去发送请求
*
* @param request
* @param callback
*/
public static Call get(Request request, DisposeDataHandle handle)
{
Call call = mOkHttpClient.newCall(request);
call.enqueue(new CommonJsonCallback(handle));
return call;
}
public static Call post(Request request, DisposeDataHandle handle)
{
Call call = mOkHttpClient.newCall(request);
call.enqueue(new CommonJsonCallback(handle));
return call;
}
public static Call downloadFile(Request request, DisposeDataHandle handle)
{
Call call = mOkHttpClient.newCall(request);
call.enqueue(new CommonFileCallback(handle));
return call;
}
}
静态代码块初始化保证了OkHttpClient的全局对象的唯一和相关参数的配置。
静态的get,post和文件下载的方法可以保证基本的网络请求需要,如果你的项目中有其他的需求,也可以在这里添加方法。
2.静态方法需要的Request来自于request包下的CommonRequest和RequestParam类
先看:RequestParam
public class RequestParams {
public ConcurrentHashMap urlParams = new ConcurrentHashMap();
public ConcurrentHashMap fileParams = new ConcurrentHashMap();
/**
* Constructs a new empty {@code RequestParams} instance.
*/
public RequestParams() {
this((Map) null);
}
/**
* Constructs a new RequestParams instance containing the key/value string
* params from the specified map.
*
* @param source
* the source key/value string map to add.
*/
public RequestParams(Map source) {
if (source != null) {
for (Map.Entry entry : source.entrySet()) {
put(entry.getKey(), entry.getValue());
}
}
}
/**
* Constructs a new RequestParams instance and populate it with a single
* initial key/value string param.
*
* @param key
* the key name for the intial param.
* @param value
* the value string for the initial param.
*/
public RequestParams(final String key, final String value) {
this(new HashMap() {
{
put(key, value);
}
});
}
/**
* Adds a key/value string pair to the request.
*
* @param key
* the key name for the new param.
* @param value
* the value string for the new param.
*/
public void put(String key, String value) {
if (key != null && value != null) {
urlParams.put(key, value);
}
}
public void put(String key, Object object) throws FileNotFoundException {
if (key != null) {
fileParams.put(key, object);
}
}
}
无非就是将String对象和Object对象(上传File时)的key-value键值对放进map对象中,
再看看CommonRequest类:
public class CommonRequest {
/**
* create the josn Request
*
* @param url
* @param json
* @return
*/
public static Request createPostJsonRequest(String url, String json) {
RequestBody requestbody = RequestBody.create(MediaType.parse("application/json"), json);
return new Request.Builder().url(url).post(requestbody).build();
}
/**
* create the key-value Request
*
* @param url
* @param params
* @return
*/
public static Request createPostRequest(String url, RequestParams params) {
FormBody.Builder mFormBodyBuild = new FormBody.Builder();
if (params != null) {
for (Map.Entry entry : params.urlParams.entrySet()) {
mFormBodyBuild.add(entry.getKey(), entry.getValue());
}
}
FormBody mFormBody = mFormBodyBuild.build();
return new Request.Builder().url(url).post(mFormBody).build();
}
/**
* ressemble the params to the url
*
* @param url
* @param params
* @return
*/
public static Request createGetRequest(String url, RequestParams params) {
StringBuilder urlBuilder = new StringBuilder(url).append("?");
if (params != null) {
for (Map.Entry entry : params.urlParams.entrySet()) {
urlBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
}
return new Request.Builder().url(urlBuilder.substring(0, urlBuilder.length() - 1)).get().build();
}
/**
* 文件上传请求
*
* @return
*/
private static final MediaType FILE_TYPE = MediaType.parse("application/octet-stream");
public static Request createMultiPostRequest(String url, RequestParams params) {
MultipartBody.Builder requestBody = new MultipartBody.Builder();
requestBody.setType(MultipartBody.FORM);
if (params != null) {
for (Map.Entry entry : params.fileParams.entrySet()) {
if (entry.getValue() instanceof File) {
requestBody.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + entry.getKey() + "\""),
RequestBody.create(FILE_TYPE, (File) entry.getValue()));
} else if (entry.getValue() instanceof String) {
requestBody.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + entry.getKey() + "\""),
RequestBody.create(null, (String) entry.getValue()));
}
}
}
return new Request.Builder().url(url).post(requestBody.build()).build();
}
}
这个类就是对request请求参数进行一个简单的封装,CommonOkHttpClient里面调用的request对象就是从这面蛇生成的。同时,我们还需要一个回调接口来监听成功和失败。
3 成功的时候我们需要对数据进行解析,所以在Response包中,有两个类,一个是处理File对象,一个是处理Json对象,我们看返回为json数据时类:
public class CommonJsonCallback implements Callback {
/**
* the logic layer exception, may alter in different app
*/
protected final String RESULT_CODE = "ecode"; // 有返回则对于http请求来说是成功的,但还有可能是业务逻辑上的错误
protected final int RESULT_CODE_VALUE = 0;
protected final String ERROR_MSG = "emsg";
protected final String EMPTY_MSG = "";
protected final String COOKIE_STORE = "Set-Cookie"; // decide the server it
// can has the value of
// set-cookie2
/**
* the java layer exception, do not same to the logic error
*/
protected final int NETWORK_ERROR = -1; // the network relative error
protected final int JSON_ERROR = -2; // the JSON relative error
protected final int OTHER_ERROR = -3; // the unknow error
/**
* 将其它线程的数据转发到UI线程
*/
private Handler mDeliveryHandler;
private DisposeDataListener mListener;
private Class> mClass;
public CommonJsonCallback(DisposeDataHandle handle) {
this.mListener = handle.mListener;
this.mClass = handle.mClass;
this.mDeliveryHandler = new Handler(Looper.getMainLooper());
}
@Override
public void onFailure(final Call call, final IOException ioexception) {
/**
* 此时还在非UI线程,因此要转发
*/
mDeliveryHandler.post(new Runnable() {
@Override
public void run() {
mListener.onFailure(new OkHttpException(NETWORK_ERROR, ioexception));
}
});
}
@Override
public void onResponse(final Call call, final Response response) throws IOException {
final String result = response.body().string();
final ArrayList cookieLists = handleCookie(response.headers());
mDeliveryHandler.post(new Runnable() {
@Override
public void run() {
handleResponse(result);
/**
* handle the cookie
*/
if (mListener instanceof DisposeHandleCookieListener) {
((DisposeHandleCookieListener) mListener).onCookie(cookieLists);
}
}
});
}
private ArrayList handleCookie(Headers headers) {
ArrayList tempList = new ArrayList();
for (int i = 0; i < headers.size(); i++) {
if (headers.name(i).equalsIgnoreCase(COOKIE_STORE)) {
tempList.add(headers.value(i));
}
}
return tempList;
}
private void handleResponse(String responseObj) {
if (null == responseObj) {
mListener.onFailure(new OkHttpException(NETWORK_ERROR, EMPTY_MSG));
return;
}
try {
if (mClass == null) {
mListener.onSuccess(responseObj);
} else {
Object obj = JSON.parseObject(responseObj.toString(), mClass);
if (obj != null) {
mListener.onSuccess(obj);
} else {
mListener.onFailure(new OkHttpException(JSON_ERROR, EMPTY_MSG));
}
}
} catch (Exception e) {
mListener.onFailure(new OkHttpException(OTHER_ERROR, e.getMessage()));
e.printStackTrace();
}
}
}
这个类要结合其他的类来看更好理解些,等下可以下载源码来看,但是这个类理解起来也是比较简单的。首先定义的对象的状态码需要改成你们自己服务器定义的。成功和失败时因为在子线程中,所以需要handle进行通信。同时针对cookie也做了单独的处理。fastjson进行解析。
private void httpGetF() {
String url="";
CommonOkHttpClient.get(CommonRequest.createGetRequest(url,null),new DisposeDataHandle(new DisposeDataListener() {
@Override
public void onSuccess(User responseObj) {}
@Override
public void onFailure(User reasonObj) {}
}));
}
private void httpPostF() {
String url="";
RequestParams requestParams=new RequestParams();
requestParams.put("key1","param1");
requestParams.put("key2","param2");
CommonOkHttpClient.post(CommonRequest.createPostRequest(url,requestParams),new DisposeDataHandle(new DisposeDataListener() {
@Override
public void onSuccess(User responseObj) {}
@Override
public void onFailure(User reasonObj) {}
}));
}
还是比较简单的哈
欢迎下载