為了不重復去寫代碼侠坎,對okhttpClient請求做封裝咒循,包含了如何跳過請求證書驗證杀餐,以及請求攔截器中對報文加密干发,響應攔截器中報文解密的實現(xiàn)如下:
1、modle的build.gradle添加依賴
implementation 'com.squareup.okhttp3:okhttp:3.7.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation 'com.alibaba:fastjson:1.2.4'
2史翘、RequestService代碼如下:
import retrofit2.Call;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Streaming;
import retrofit2.http.Url;
/**
* 作者:created by fanHongJiao
*/
public class RequestService {
public interface commonService {
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("{reqPath}")
Call<ResponseBody> createCommit(@Path(value = "reqPath", encoded = true) String path, @Body RequestBody route);
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("")
Call<ResponseBody> createUilCommit(@Url String url, @Body RequestBody route);
}
public interface downloadFileService {
@Streaming
@GET
Call<ResponseBody> downloadFileWithDynamicUrlSync(@Url String fileUrl);
}
}
3枉长、RequestBodyFactory代碼如下
package okhttpclientDemo.utils;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
/**
* 作者:created by fanHongJiao
*/
public class RequestBodyFactory {
public static Call<ResponseBody> requestNet(Object body,String reqPath) throws JSONException {
RequestService.commonService service=NetManger.getInstance().CreateService(RequestService.commonService.class);
JSONObject jsonObject=new JSONObject();
JSONObject heard=new JSONObject();
Date time= Calendar.getInstance().getTime();
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
heard.put("time",format.format(time));
jsonObject.put("heard",heard);
RequestBody requestBody=RequestBody.create(MediaType.parse("Content-Type,application/json"),jsonObject.toString());
Call<ResponseBody> commit=service.createCommit(reqPath,requestBody);
return commit;
}
}
4、NetManger代碼
package okhttpclientDemo.utils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
import okhttpclientDemo.utils.e2ee.RequestInterceptor;
import okhttpclientDemo.utils.e2ee.ResponseInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* 作者:created by fanHongJiao
*/
public class NetManger {
private static NetManger instance;
Retrofit retrofit;
public static NetManger getInstance() {
if (instance == null) {
instance = new NetManger();
}
return instance;
}
private NetManger() {
//跳過http驗證
X509TrustManager xtm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{xtm}, new SecureRandom());
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
};
OkHttpClient client = new OkHttpClient().newBuilder()
.sslSocketFactory(sslContext.getSocketFactory())//跳過hhtp驗證
.hostnameVerifier(DO_NOT_VERIFY)
.addInterceptor(new RequestInterceptor())//攔截器
.addInterceptor(new ResponseInterceptor())
.connectTimeout(5, TimeUnit.SECONDS)//鏈接超時時間
.readTimeout(120, TimeUnit.SECONDS)
.callTimeout(120, TimeUnit.SECONDS)
.build();
//配置你的gson
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd hh:mm:ss")
.create();
retrofit = new Retrofit.Builder()
.baseUrl(Constant.BaseUrl)//url
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
}
public <T> T CreateService(Class tClass) {
T service = (T) retrofit.create(tClass);
return service;
}
}
5琼讽、IResponse代碼如下:
package okhttpclientDemo.utils;
import org.json.JSONObject;
/**
*
* 作者:created by fanHongJiao
*/
public interface IResponse {
void success(JSONObject object);
void failed(String code,String message,Object obj);
}
6必峰、HttpRequestManager代碼如下:
package okhttpclientDemo.utils;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
*
* 作者:created by fanHongJiao
*/
public class HttpRequestManager {
public static final void postRequestObject(JSONObject body,String path,final IResponse callBack) throws JSONException {
Call<ResponseBody>responseBodyCall=RequestBodyFactory.requestNet(body,path);
responseBodyCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
String string = response.body().string();
callBack.success(body);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
callBack.failed("-3", t.getMessage(), t);
//連接失敗
}
});
}
}
7、Constant代碼如下:
package okhttpclientDemo.utils;
/**
*常量定義
* 作者:created by fanHongJiao
*/
public class Constant {
public static final String BaseUrl="https://220.241.39.45/cibs/sit/";
public static final String requestUrl="custpc/generateGetSessionKey.do";
}
8钻蹬、E2eeUtils用于模擬加解密吼蚁,具體如何加密根據(jù)需求
package okhttpclientDemo.utils.e2ee;
/**
* 模仿加密,如何加密根據(jù)需求添加代碼
* 作者:created by fanHongJiao
*/
public class E2eeUtils {
public E2eeUtils() {
}
/**
* 加密操作
* @param bytes
* @return
*/
public String encrypt(byte[] bytes) {
String enStr = null;
return enStr;
}
/**
* 解密
* @param bytes
* @return
*/
public String decrypt(byte[] bytes){
String decStr=null;
return decStr;
}
}
9问欠、RequestInterceptor請求攔截器肝匆,在請求發(fā)出之前執(zhí)行,用于放加密顺献,統(tǒng)一的請求頭參數(shù)代碼如下:
package okhttpclientDemo.utils.e2ee;
import java.io.IOException;
import java.nio.charset.Charset;
import okhttp3.MediaType;
import okhttpclientDemo.utils.e2ee.E2eeUtils;
import okio.Buffer;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* 請求攔截器,可對報文加密旗国, 或者添加公共參數(shù)等
* 作者:created by fanHongJiao
*/
public class RequestInterceptor implements Interceptor {
private static boolean isE2ee = false;//是否加密,true表示需要加密
private static final String CHARSET = "UTF-8";
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
RequestBody requestBody = request.body();
String requestUrl = request.url().toString();
//判斷是否需要加密
if (isE2ee) {
Buffer buffer = new Buffer();
//做加密注整,以簡單的md5加密為例
E2eeUtils e2eeUtils = new E2eeUtils();
requestBody.writeTo(buffer);
Charset charset;
MediaType contentType = requestBody.contentType();
charset = contentType.charset(Charset.forName("UTF-8"));
String requestString = buffer.readString(charset);//讀取請求體
String encrytParams = null;
encrytParams = e2eeUtils.encrypt(requestString.getBytes(CHARSET));//加密
RequestBody body = chain.request().body();
MediaType contentType1 = body.contentType();
if(encrytParams!=null){
requestBody = RequestBody.create(contentType1, encrytParams.trim());}
request = chain.request()
.newBuilder()
.header("Accept-Language", "en")//okhttp請求頭提交語言
.post(requestBody)
.build();
}
return chain.proceed(request);
}
}
10能曾、ResponseInterceptor請求數(shù)據(jù)返回時執(zhí)行,可處理報文解密肿轨,代碼如下:
package okhttpclientDemo.utils.e2ee;
import java.io.IOException;
import java.nio.charset.Charset;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttpclientDemo.utils.e2ee.E2eeUtils;
import okio.Buffer;
import okio.BufferedSource;
/**
* 請求響應攔截器借浊,處理返回的加密報文得解密
* 作者:created by fanHongJiao
*/
public class ResponseInterceptor implements Interceptor {
private static boolean isE2ee = false;//是否解密,true表示需要解密
private static final String CHARSET = "UTF-8";
@Override
public Response intercept(Chain chain) throws IOException {
Request request=chain.request();
Response response=chain.proceed(request);
ResponseBody responseBody=response.body();
if(responseBody!=null){
//獲取響應body
BufferedSource source=responseBody.source();
source.request(Long.MAX_VALUE);
Buffer buffer=source.buffer();
Charset charset=Charset.forName("UTF-8");
MediaType contentType=responseBody.contentType();
charset=contentType.charset(charset);
String bodyString=buffer.clone().readString(charset);
String responseData=null;
if(isE2ee){
E2eeUtils e2eeUtils=new E2eeUtils();
responseData=e2eeUtils.decrypt(bodyString.getBytes(CHARSET));//解密
if(responseData!=null) {
ResponseBody newResponseBody = ResponseBody.create(contentType, responseData);
response=response
.newBuilder()
.body(newResponseBody)
.build();
return response;
}
}
}
return response;
}
}
11萝招、OkHttpClientActivity蚂斤,測試請求頁面代碼如下:
package okhttpclientDemo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.example.viewpaerdemo.R;
import org.json.JSONException;
import org.json.JSONObject;
import okhttpclientDemo.utils.Constant;
import okhttpclientDemo.utils.HttpRequestManager;
import okhttpclientDemo.utils.IResponse;
public class OkHttpClientActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ok_http_client);
JSONObject body=new JSONObject();
try {
body.put("heard","heard");
} catch (JSONException e) {
e.printStackTrace();
}
try {
HttpRequestManager.postRequestObject(body, Constant.requestUrl, new IResponse() {
@Override
public void success(JSONObject object) {
Log.e("success:",object.toString());
}
@Override
public void failed(String code, String message, Object obj) {
Log.e("failed:",obj.toString());
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
}
完結。