Android-第三方框架-网络请求之okhttp
程序员文章站
2024-01-17 19:51:58
...
简介
OkHttp 是 Square 公司开源的针对 Java 和 Android 程序,封装的一个高性能 http 请求库,支持同步、异步,封装了线程池,封装了数据转换,封装了参数使用、错误处理等,api 使用起来更加方便。而且实现了spdy、http2、websocket协议。
应用
OkHttp 是基于http协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟HttpClient, HttpUrlConnection的职责是一样的。因此需要再封装一层。实现一行代码实现http请求。不多说,代码撸起来…
compile 'com.squareup.okhttp3:okhttp:3.8.1'
- 支持https请求,添加cer证书
/**
* 证书名称,https访问不同网站需要的cer证书
* @param cername
*/
HttpRequest(Context context,String cername) {
httpBuilder = new OkHttpClient.Builder();
if (cername != null)
addSSL(context,cername);
}
/**
* 添加证书许可
* 证书放在asset下
* @param cerName 证书名称
*/
public void addSSL(Context context,String cerName) {
//获取证书数据
InputStream zhengshu = null;
try {
zhengshu = context.getAssets().open(cerName);
//设置验证当前的证书
SSLSocketFactory sslSocketFactory = getSocketFactory(zhengshu);
if (sslSocketFactory != null) {
httpBuilder.sslSocketFactory(sslSocketFactory);
httpBuilder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @param certificates 客户端添加的信任证书证书
* @return 证书的SSLSock
*/
private SSLSocketFactory getSocketFactory(InputStream... certificates) {
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
int index = 0;
for (InputStream certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
try {
if (certificate != null)
certificate.close();
} catch (IOException e) {
}
}
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
return sslContext.getSocketFactory();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
- 服务器请求数据
/**
* 带参数的服务交换数据
* @param url
* @param paramsMap
* @param responseCallBack
*/
public void requestAnsy(int httpType, String url, HashMap<String, Object> paramsMap, final HttpResponseCallBack responseCallBack) {
final Request request = structRequest(httpType, url, paramsMap);
new Thread(new Runnable() {
@Override
public void run() {
defaultExcute(request, responseCallBack);
}
}).start();
}
/**
* 构建Request
*
* @param requestType
* @param actionUrl
* @param paramsMap
* @return
*/
private Request structRequest(int requestType, String actionUrl, HashMap<String, Object> paramsMap) {
switch (requestType) {
case TYPE_GET:
actionUrl = getFullUrl(actionUrl, paramsMap);
return new Request.Builder().url(actionUrl).build();
case TYPE_POST:
MultipartBody.Builder builder = new MultipartBody.Builder();
if (paramsMap != null) {
for (String key : paramsMap.keySet()) {
Object object = paramsMap.get(key);
builder.addFormDataPart(key, object.toString());
}
RequestBody formBody = builder.build();
return new Request.Builder().url(actionUrl).post(formBody).build();
} else {
return new Request.Builder().url(actionUrl).build();
}
default:
return null;
}
}
/**
* get请求拼接url数据
* url 添加参数
*
* @param paramsMap
* @return
*/
private String getFullUrl(String actionUrl, HashMap<String, Object> paramsMap) {
if (paramsMap != null) {
StringBuilder tempParams = new StringBuilder(actionUrl);
try {
//处理参数
int pos = 0;
for (String key : paramsMap.keySet()) {
if (pos > 0) {
tempParams.append("&");
}
//对参数进行URLEncoder
tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key).toString(), "utf-8")));
pos++;
}
//返回补全请求地址
return tempParams.toString();
} catch (Exception e) {
}
}
return actionUrl;
}
- 请求结果回调
/**
* 默认服务请求
*
* @param request
* @param responseCallBack
* @param <T>
*/
private <T> void defaultExcute(Request request, HttpResponseCallBack responseCallBack) {
String type = request.method();
if (type.equalsIgnoreCase("Get")) {
try {
Response response = httpBuilder.build().newCall(request).execute();
if (response.isSuccessful()) {
if (responseCallBack != null)
responseCallBack.onSuccess((T) response);
} else {
if (responseCallBack != null)
responseCallBack.onFail(null);
}
} catch (IOException e) {
e.printStackTrace();
if (responseCallBack != null)
responseCallBack.onFail(e);
}
} else {
runServiceExecute(request, responseCallBack);
}
}
/**
* 执行服务post请求
* @param request
* @param responseCallBack
*/
private<T> void runServiceExecute(Request request,final HttpResponseCallBack responseCallBack) {
httpBuilder.build().newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
if (responseCallBack != null)
responseCallBack.onFail(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
if (responseCallBack != null)
responseCallBack.onSuccess((T) response);
} else {
if (responseCallBack != null)
responseCallBack.onFail(null);
}
}
});
}
完整代码
import android.content.Context;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.util.HashMap;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* 与服务器之间数据的交互,
* Created by gm on 2017/3/9.
*/
public class HttpRequest {
private OkHttpClient.Builder httpBuilder; //okHttpClient 实例
public static final int TYPE_GET = 0;
public static final int TYPE_POST = 1;
/**
* 证书名称,https访问不同网站需要的cer证书
* @param cername
*/
HttpRequest(Context context,String cername) {
httpBuilder = new OkHttpClient.Builder();
if (cername != null)
addSSL(context,cername);
}
/**
* 添加证书许可
* 证书放在asset下
* @param cerName 证书名称
*/
public void addSSL(Context context,String cerName) {
//获取证书数据
InputStream zhengshu = null;
try {
zhengshu = context.getAssets().open(cerName);
//设置验证当前的证书
SSLSocketFactory sslSocketFactory = getSocketFactory(zhengshu);
if (sslSocketFactory != null) {
httpBuilder.sslSocketFactory(sslSocketFactory);
httpBuilder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @param certificates 客户端添加的信任证书证书
* @return 证书的SSLSock
*/
private SSLSocketFactory getSocketFactory(InputStream... certificates) {
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
int index = 0;
for (InputStream certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
try {
if (certificate != null)
certificate.close();
} catch (IOException e) {
}
}
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
return sslContext.getSocketFactory();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 带参数的服务交换数据
* @param url
* @param paramsMap
* @param responseCallBack
*/
public void requestAnsy(int httpType, String url, HashMap<String, Object> paramsMap, final HttpResponseCallBack responseCallBack) {
final Request request = structRequest(httpType, url, paramsMap);
new Thread(new Runnable() {
@Override
public void run() {
defaultExcute(request, responseCallBack);
}
}).start();
}
/**
* 构建Request
*
* @param requestType
* @param actionUrl
* @param paramsMap
* @return
*/
private Request structRequest(int requestType, String actionUrl, HashMap<String, Object> paramsMap) {
switch (requestType) {
case TYPE_GET:
actionUrl = getFullUrl(actionUrl, paramsMap);
return new Request.Builder().url(actionUrl).build();
case TYPE_POST:
MultipartBody.Builder builder = new MultipartBody.Builder();
if (paramsMap != null) {
for (String key : paramsMap.keySet()) {
Object object = paramsMap.get(key);
builder.addFormDataPart(key, object.toString());
}
RequestBody formBody = builder.build();
return new Request.Builder().url(actionUrl).post(formBody).build();
} else {
return new Request.Builder().url(actionUrl).build();
}
default:
return null;
}
}
/**
* get请求拼接url数据
* url 添加参数
*
* @param paramsMap
* @return
*/
private String getFullUrl(String actionUrl, HashMap<String, Object> paramsMap) {
if (paramsMap != null) {
StringBuilder tempParams = new StringBuilder(actionUrl);
try {
//处理参数
int pos = 0;
for (String key : paramsMap.keySet()) {
if (pos > 0) {
tempParams.append("&");
}
//对参数进行URLEncoder
tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key).toString(), "utf-8")));
pos++;
}
//返回补全请求地址
return tempParams.toString();
} catch (Exception e) {
}
}
return actionUrl;
}
/**
* 默认服务请求
*
* @param request
* @param responseCallBack
* @param <T>
*/
private <T> void defaultExcute(Request request, HttpResponseCallBack responseCallBack) {
String type = request.method();
if (type.equalsIgnoreCase("Get")) {
try {
Response response = httpBuilder.build().newCall(request).execute();
if (response.isSuccessful()) {
if (responseCallBack != null)
responseCallBack.onSuccess((T) response);
} else {
if (responseCallBack != null)
responseCallBack.onFail(null);
}
} catch (IOException e) {
e.printStackTrace();
if (responseCallBack != null)
responseCallBack.onFail(e);
}
} else {
runServiceExecute(request, responseCallBack);
}
}
/**
* 执行服务post请求
* @param request
* @param responseCallBack
*/
private<T> void runServiceExecute(Request request,final HttpResponseCallBack responseCallBack) {
httpBuilder.build().newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
if (responseCallBack != null)
responseCallBack.onFail(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
if (responseCallBack != null)
responseCallBack.onSuccess((T) response);
} else {
if (responseCallBack != null)
responseCallBack.onFail(null);
}
}
});
}
}
- 回调接口
public interface HttpResponseCallBack{
/**
* success on response,return response
* @param result
*/
<T> void onSuccess(T result);
/**
* faile on response ,if e is null,which the service is noconnect,
* @param e
*/
void onFail(Exception e);
}
应用
new HttpRequest(getApplicationContext(),null).requestAnsy(HttpRequest.TYPE_GET,url, null, new HttpResponseCallBack() {
@Override
public <T> void onSuccess(T result) {
Response resultRes = (Response)result;
.......
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFail(Exception e) {
}
});
最后记得在AndroidManifest.xml添加网络访问权限:
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
推荐阅读
-
Android-第三方框架-网络请求之okhttp
-
Android Retrofit2+rxjava2+Mvp基于okhttp3网络请求框架的使用 一 框架配置
-
Android Retrofit2+rxjava2+Mvp基于okhttp3网络请求框架的使用 三 文件上传(支持多文件/多图片上传)
-
Android 网络请求框架解析之okhttp与okio
-
带你一步步剖析Retrofit 源码解析:一款基于 OkHttp 实现的网络请求框架 android源码解析网络请求OKHTTPRetrofit
-
Retrofit 2.0使用详解,配合OkHttp、Gson,Android最强网络请求框架
-
Android网络请求框架使用 -- OkHttp
-
Android Retrofit2+rxjava2+Mvp基于okhttp3网络请求框架的使用 三 文件上传(支持多文件/多图片上传)
-
Android 网络请求框架解析之okhttp与okio
-
Android Retrofit2+rxjava2+Mvp基于okhttp3网络请求框架的使用 一 框架配置