OkHttp协议
okhttp是一个第三方类库,用于android中请求网络
这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso和LeakCanary)
文件下载用Get方式
OkHttpClient okHttpClient = new OkHttpClient.Builder().callTimeout(5, TimeUnit.SECONDS).readTimeout(5, TimeUnit.SECONDS).build();Request request = new Request.Builder().url(u).get().build();Call call = okHttpClient.newCall(request);call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {}@Overridepublic void onResponse(Call call, Response response) throws IOException {ResponseBody body = response.body();long length = body.contentLength();Message message = Message.obtain();message.what = Model.DownLoad_Max;message.obj = (int)length;handler.sendMessage(message);InputStream inputStream = body.byteStream();FileOutputStream fileOutputStream = new FileOutputStream(path);byte[] bytes = new byte[1024];int len = 0;int count = 0;while ((len=inputStream.read(bytes))!=-1) {count+=len;fileOutputStream.write(bytes,0,len);Message message1 = Message.obtain();message1.what = Model.DownLoad_Progress;message1.obj = count;handler.sendMessage(message1);}}});
文件上传用Post方式
OkHttpClient okHttpClient = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).callTimeout(5, TimeUnit.SECONDS).build();MultipartBody multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("file",filename, RequestBody.create(MediaType.parse("image/jpg"),new File(path))).build();Request request = new Request.Builder().url(u).post(multipartBody).build();Call call = okHttpClient.newCall(request);call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {}@Overridepublic void onResponse(Call call, Response response) throws IOException {handler.sendEmptyMessage(Model.UpLoad_Finish);}});
OkHttp协议封装
将OkHttp封装成工具类并写上传和下载方法,代码如下:
public static OkHttpClient okHttpClient;private static OkHttpUtils okHttpUtils = new OkHttpUtils();private OkHttpUtils(){}public static OkHttpUtils getOkHttpUtils(){okHttpClient = new OkHttpClient.Builder().callTimeout(5, TimeUnit.SECONDS).readTimeout(5,TimeUnit.SECONDS).build();return okHttpUtils;}public void get(String url, final CallBack callBack){Request request = new Request.Builder().get().url(url).build();Call call = okHttpClient.newCall(request);call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {callBack.onError(e.getMessage());}@Overridepublic void onResponse(Call call, Response response) throws IOException {callBack.onSuccess(response);}});}public void post(String url, HashMap<String,String> map, final CallBack callBack){Set<Map.Entry<String, String>> entries = map.entrySet();FormBody.Builder builder = new FormBody.Builder();for (Map.Entry<String, String> entrie : entries) {String key = entrie.getKey();String value = entrie.getValue();builder.add(key,value);}FormBody formBody = builder.build();Request request = new Request.Builder().post(formBody).url(url).build();Call call = okHttpClient.newCall(request);call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {callBack.onError(e.getMessage());}@Overridepublic void onResponse(Call call, Response response) throws IOException {callBack.onSuccess(response);}});}
OkHttp拦截器
主要用于拦截发送信息
public static OkHttpClient okHttpClient;private static OkHttpUtils okHttpUtils = new OkHttpUtils();private OkHttpUtils(){}public static OkHttpUtils getOkHttpUtils(){okHttpClient = new OkHttpClient.Builder().callTimeout(5, TimeUnit.SECONDS).readTimeout(5,TimeUnit.SECONDS).addInterceptor(httpLoggingInterceptor).addInterceptor(interceptor).build();return okHttpUtils;}static HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {@Overridepublic void log(String message) {Log.d("###",message);}});static Interceptor interceptor = new Interceptor() {@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request().newBuilder().header("token", "token").build();return chain.proceed(request);}};
SpringBoot——集成Okhttp3
1.pom依赖:
<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>3.10.0</version>
</dependency>
2.okhttp工具类:
public class OkHttpUtils {private static volatile OkHttpClient okHttpClient = null;private static volatile Semaphore semaphore = null;private Map<String, String> headerMap;private Map<String, String> paramMap;private String url;private Request.Builder request;/*** 初始化okHttpClient,并且允许https访问*/private OkHttpUtils() {if (okHttpClient == null) {synchronized (OkHttpUtils.class) {if (okHttpClient == null) {TrustManager[] trustManagers = buildTrustManagers();okHttpClient = new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS).writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS).sslSocketFactory(createSSLSocketFactory(trustManagers), (X509TrustManager) trustManagers[0]).hostnameVerifier((hostName, session) -> true).retryOnConnectionFailure(true).build();addHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");}}}}/*** 用于异步请求时,控制访问线程数,返回结果** @return*/private static Semaphore getSemaphoreInstance() {//只能1个线程同时访问synchronized (OkHttpUtils.class) {if (semaphore == null) {semaphore = new Semaphore(0);}}return semaphore;}/*** 创建OkHttpUtils** @return*/public static OkHttpUtils builder() {return new OkHttpUtils();}/*** 添加url** @param url* @return*/public OkHttpUtils url(String url) {this.url = url;return this;}/*** 添加参数** @param key 参数名* @param value 参数值* @return*/public OkHttpUtils addParam(String key, String value) {if (paramMap == null) {paramMap = new LinkedHashMap<>(16);}paramMap.put(key, value);return this;}/*** 添加请求头** @param key 参数名* @param value 参数值* @return*/public OkHttpUtils addHeader(String key, String value) {if (headerMap == null) {headerMap = new LinkedHashMap<>(16);}headerMap.put(key, value);return this;}/*** 初始化get方法** @return*/public OkHttpUtils get() {request = new Request.Builder().get();StringBuilder urlBuilder = new StringBuilder(url);if (paramMap != null) {urlBuilder.append("?");try {for (Map.Entry<String, String> entry : paramMap.entrySet()) {urlBuilder.append(URLEncoder.encode(entry.getKey(), "utf-8")).append("=").append(URLEncoder.encode(entry.getValue(), "utf-8")).append("&");}} catch (Exception e) {e.printStackTrace();}urlBuilder.deleteCharAt(urlBuilder.length() - 1);}request.url(urlBuilder.toString());return this;}/*** 初始化post方法** @param isJsonPost true等于json的方式提交数据,类似postman里post方法的raw* false等于普通的表单提交* @return*/public OkHttpUtils post(boolean isJsonPost) {RequestBody requestBody;if (isJsonPost) {String json = "";if (paramMap != null) {json = JSON.toJSONString(paramMap);}requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);} else {FormBody.Builder formBody = new FormBody.Builder();if (paramMap != null) {paramMap.forEach(formBody::add);}requestBody = formBody.build();}request = new Request.Builder().post(requestBody).url(url);return this;}/*** 同步请求** @return*/public String sync() {setHeader(request);try {Response response = okHttpClient.newCall(request.build()).execute();assert response.body() != null;return response.body().string();} catch (IOException e) {e.printStackTrace();return "请求失败:" + e.getMessage();}}/*** 异步请求,有返回值*/public String async() {StringBuilder buffer = new StringBuilder("");setHeader(request);okHttpClient.newCall(request.build()).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {buffer.append("请求出错:").append(e.getMessage());}@Overridepublic void onResponse(Call call, Response response) throws IOException {assert response.body() != null;buffer.append(response.body().string());getSemaphoreInstance().release();}});try {getSemaphoreInstance().acquire();} catch (InterruptedException e) {e.printStackTrace();}return buffer.toString();}/*** 异步请求,带有接口回调** @param callBack*/public void async(ICallBack callBack) {setHeader(request);okHttpClient.newCall(request.build()).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {callBack.onFailure(call, e.getMessage());}@Overridepublic void onResponse(Call call, Response response) throws IOException {assert response.body() != null;callBack.onSuccessful(call, response.body().string());}});}/*** 为request添加请求头** @param request*/private void setHeader(Request.Builder request) {if (headerMap != null) {try {for (Map.Entry<String, String> entry : headerMap.entrySet()) {request.addHeader(entry.getKey(), entry.getValue());}} catch (Exception e) {e.printStackTrace();}}}/*** 生成安全套接字工厂,用于https请求的证书跳过** @return*/private static SSLSocketFactory createSSLSocketFactory(TrustManager[] trustAllCerts) {SSLSocketFactory ssfFactory = null;try {SSLContext sc = SSLContext.getInstance("SSL");sc.init(null, trustAllCerts, new SecureRandom());ssfFactory = sc.getSocketFactory();} catch (Exception e) {e.printStackTrace();}return ssfFactory;}private static TrustManager[] buildTrustManagers() {return new TrustManager[]{new X509TrustManager() {@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}}};}/*** 自定义一个接口回调*/public interface ICallBack {void onSuccessful(Call call, String data);void onFailure(Call call, String errorMsg);}
}
3.测试
@SpringBootTest
class SpringBootOkhttp3ApplicationTests {@Testvoid contextLoads() {// get请求,方法顺序按照这种方式,切记选择post/get一定要放在倒数第二,同步或者异步倒数第一,才会正确执行OkHttpUtils.builder().url("请求地址,http/https都可以")// 有参数的话添加参数,可多个.addParam("参数名", "参数值").addParam("参数名", "参数值")// 也可以添加多个.addHeader("Content-Type", "application/json; charset=utf-8").get()// 可选择是同步请求还是异步请求//.async();.sync();System.out.println("----------------------------------");// post请求,分为两种,一种是普通表单提交,一种是json提交OkHttpUtils.builder().url("请求地址,http/https都可以")// 有参数的话添加参数,可多个.addParam("参数名", "参数值").addParam("参数名", "参数值")// 也可以添加多个.addHeader("Content-Type", "application/json; charset=utf-8")// 如果是true的话,会类似于postman中post提交方式的raw,用json的方式提交,不是表单// 如果是false的话传统的表单提交.post(true).sync();// 选择异步有两个方法,一个是带回调接口,一个是直接返回结果OkHttpUtils.builder().url("").post(false).async();OkHttpUtils.builder().url("").post(false).async(new OkHttpUtils.ICallBack() {@Overridepublic void onSuccessful(Call call, String data) {// 请求成功后的处理}@Overridepublic void onFailure(Call call, String errorMsg) {// 请求失败后的处理}});}
}