OkHttp是一个高效的HTTP客户端,在Android中用的比较多,也可以用在Java中;本文主要介绍OkHttp在java中的使用,文中所使用到的软件版本:Java 1.8.0_191、SpringBoot2.2.1.RELEASE。
1、OkHttp特点
a、支持HTTP/2,允许所有同一个主机地址的请求共享同一个socket连接
b、连接池减少请求延时
c、透明的GZIP压缩减少响应数据的大小
d、缓存响应内容,避免一些完全重复的请求
2、服务端
3、调用Http接口
添加依赖如下:
<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.8.1</version> </dependency>
由于okHttp 4.x用到了kotline,所以需要kotline的环境;在IDEA中可以直接下载kotline的插件。
3.1、GET请求
@Test public void get() throwsIOException { String requestPath = "http://localhost:8080/demo/httptest/getUser?userId=1000&userName=李白"; OkHttpClient client = newOkHttpClient(); Request request = newRequest.Builder() .url(requestPath).get().build(); Response response =client.newCall(request).execute(); System.out.println("get返回状态:" +response.code()); System.out.println("get返回结果:" +response.body().string()); response.close(); }
3.2、POST请求(发送键值对数据)
@Test public void post() throwsIOException { String requestPath = "http://localhost:8080/demo/httptest/getUser"; OkHttpClient client = newOkHttpClient(); RequestBody body = newFormBody.Builder() .add("userId", "1000") .add("userName", "李白") .build(); Request request = newRequest.Builder() .url(requestPath).post(body).build(); Response response =client.newCall(request).execute(); System.out.println("post返回状态:" +response.code()); System.out.println("post返回结果:" +response.body().string()); response.close(); }
3.3、POST请求(发送JSON数据)
@Test public void post2() throwsIOException { String requestPath = "http://localhost:8080/demo/httptest/addUser"; OkHttpClient client = newOkHttpClient(); String param = "{\"userId\": \"1001\",\"userName\":\"杜甫\"}"; RequestBody body = RequestBody.create(param, MediaType.get("application/json; charset=utf-8")); Request request = newRequest.Builder() .url(requestPath) .post(body) .build(); Response response =client.newCall(request).execute(); System.out.println("post2返回状态:" +response.code()); System.out.println("post2返回结果:" +response.body().string()); response.close(); }
3.4、上传文件
@Test public void upload() throwsIOException { String requestPath = "http://localhost:8080/demo/httptest/upload"; OkHttpClient client = newOkHttpClient(); File file = new File("d:/a.jpg"); RequestBody body = RequestBody.create(file, MediaType.get("file/*")); Request request = newRequest.Builder() .url(requestPath) .post(body) .build(); Response response =client.newCall(request).execute(); System.out.println("upload返回状态:" +response.code()); System.out.println("upload返回结果:" +response.body().string()); response.close(); }
3.5、上传文件及发送键值对数据
@Test public void mulit() throwsIOException { String requestPath = "http://localhost:8080/demo/httptest/multi"; OkHttpClient client = newOkHttpClient(); File file = new File("d:/a.jpg"); RequestBody body = newMultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", file.getName(), RequestBody.create(file, MediaType.parse("image/png"))) .addFormDataPart("param1", "参数1") .addFormDataPart("param2", "参数2") .build(); Request request = newRequest.Builder() .url(requestPath) .post(body) .build(); Response response =client.newCall(request).execute(); System.out.println("mulit返回状态:" +response.code()); System.out.println("mulit返回结果:" +response.body().string()); response.close(); }
3.6、完整例子
packagecom.inspur.demo.http.client; import okhttp3.*; importorg.junit.Test; importjava.io.File; importjava.io.IOException; /*** 通过OkHttp调用Http接口 */ public classOkHttpCase { /*** GET请求 */@Test public void get() throwsIOException { String requestPath = "http://localhost:8080/demo/httptest/getUser?userId=1000&userName=李白"; OkHttpClient client = newOkHttpClient(); Request request = newRequest.Builder() .url(requestPath).get().build(); Response response =client.newCall(request).execute(); System.out.println("get返回状态:" +response.code()); System.out.println("get返回结果:" +response.body().string()); response.close(); } /*** POST请求(发送键值对数据) */@Test public void post() throwsIOException { String requestPath = "http://localhost:8080/demo/httptest/getUser"; OkHttpClient client = newOkHttpClient(); RequestBody body = newFormBody.Builder() .add("userId", "1000") .add("userName", "李白") .build(); Request request = newRequest.Builder() .url(requestPath).post(body).build(); Response response =client.newCall(request).execute(); System.out.println("post返回状态:" +response.code()); System.out.println("post返回结果:" +response.body().string()); response.close(); } /*** POST请求(发送json数据) */@Test public void post2() throwsIOException { String requestPath = "http://localhost:8080/demo/httptest/addUser"; OkHttpClient client = newOkHttpClient(); String param = "{\"userId\": \"1001\",\"userName\":\"杜甫\"}"; RequestBody body = RequestBody.create(param, MediaType.get("application/json; charset=utf-8")); Request request = newRequest.Builder() .url(requestPath) .post(body) .build(); Response response =client.newCall(request).execute(); System.out.println("post2返回状态:" +response.code()); System.out.println("post2返回结果:" +response.body().string()); response.close(); } /*** 上传文件 */@Test public void upload() throwsIOException { String requestPath = "http://localhost:8080/demo/httptest/upload"; OkHttpClient client = newOkHttpClient(); File file = new File("d:/a.jpg"); RequestBody body = RequestBody.create(file, MediaType.get("file/*")); Request request = newRequest.Builder() .url(requestPath) .post(body) .build(); Response response =client.newCall(request).execute(); System.out.println("upload返回状态:" +response.code()); System.out.println("upload返回结果:" +response.body().string()); response.close(); } /*** 上传文件及发送键值对数据 */@Test public void mulit() throwsIOException { String requestPath = "http://localhost:8080/demo/httptest/multi"; OkHttpClient client = newOkHttpClient(); File file = new File("d:/a.jpg"); RequestBody body = newMultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", file.getName(), RequestBody.create(file, MediaType.parse("image/png"))) .addFormDataPart("param1", "参数1") .addFormDataPart("param2", "参数2") .build(); Request request = newRequest.Builder() .url(requestPath) .post(body) .build(); Response response =client.newCall(request).execute(); System.out.println("mulit返回状态:" +response.code()); System.out.println("mulit返回结果:" +response.body().string()); response.close(); } }
4、调用Https接口
与调用Http接口不一样的部分主要在设置sslSocketFactory和hostnameVerifier部分,下面用GET请求来演示sslSocketFactory和hostnameVerifier的设置,其他调用方式类似。
packagecom.inspur.demo.http.client; importcom.inspur.demo.common.util.FileUtil; importokhttp3.OkHttpClient; importokhttp3.Request; importokhttp3.Response; importorg.junit.Test; import javax.net.ssl.*; importjava.io.File; importjava.io.FileInputStream; importjava.io.IOException; importjava.security.KeyStore; importjava.security.cert.CertificateException; importjava.security.cert.X509Certificate; /*** 通过OkHttp调用Https接口 */ public classOkHttpHttpsCase { /** 请求有权威证书的地址 */@Test public void test() throwsIOException { String requestPath = "https://www.baidu.com/"; OkHttpClient client = newOkHttpClient.Builder() //.connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS)) .build(); Request request = newRequest.Builder() .url(requestPath).get().build(); Response response =client.newCall(request).execute(); System.out.println("get返回状态:" +response.code()); System.out.println("get返回结果:" +response.body().string()); response.close(); } /*** 请求自定义证书的地址,不需要客户端证书 * * @throwsException */@Test public void test2() throwsException { String requestPath = "https://10.40.103.48:9010/zsywservice"; //获取信任证书库 KeyStore trustStore = getkeyStore("jks", "d:/temp/cacerts", "123456"); //KeyStore trustStore = null; //trustStore为null也可以 OkHttpClient client = newOkHttpClient.Builder() .sslSocketFactory(getSSLSocketFactory(null, null, trustStore), newDefaultTrustManager()) .hostnameVerifier((s, sslSession) -> true).build(); Request request = newRequest.Builder() .url(requestPath).get().build(); Response response =client.newCall(request).execute(); System.out.println("get返回状态:" +response.code()); System.out.println("get返回结果:" +response.body().string()); response.close(); } /*** 请求自定义证书的地址,需要客户端证书 * * @throwsIOException */@Test public void test3() throwsException { String requestPath = "https://10.40.103.48:9016/zsywservice"; //获取客户端证书 KeyStore keyStore = getkeyStore("pkcs12", "d:/client.p12", "123456"); //获取信任证书库 KeyStore trustStore = getkeyStore("jks", "d:/temp/cacerts", "123456"); //KeyStore trustStore = null; //trustStore为null也可以 OkHttpClient client = newOkHttpClient.Builder() .sslSocketFactory(getSSLSocketFactory(keyStore, "123456", trustStore), newDefaultTrustManager()) .hostnameVerifier((s, sslSession) -> true).build(); Request request = newRequest.Builder() .url(requestPath).get().build(); Response response =client.newCall(request).execute(); System.out.println("get返回状态:" +response.code()); System.out.println("get返回结果:" +response.body().string()); response.close(); } /*** 获取证书 * * @return */ privateKeyStore getkeyStore(String type, String filePath, String password) { KeyStore keySotre = null; FileInputStream in = null; try{ keySotre =KeyStore.getInstance(type); in = new FileInputStream(newFile(filePath)); keySotre.load(in, password.toCharArray()); } catch(Exception e) { e.printStackTrace(); } finally{ FileUtil.close(in); } returnkeySotre; } private SSLSocketFactory getSSLSocketFactory(KeyStore keyStore, String keyStorePassword, KeyStore trustStore) throwsException { KeyManager[] keyManagers = null; TrustManager[] trustManagers = null; if (keyStore != null) { KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); keyManagerFactory.init(keyStore, keyStorePassword.toCharArray()); keyManagers =keyManagerFactory.getKeyManagers(); } if (trustStore != null) { TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509"); trustManagerFactory.init(trustStore); trustManagers =trustManagerFactory.getTrustManagers(); } else{ trustManagers = new TrustManager[]{newDefaultTrustManager()}; } //设置服务端支持的协议 SSLContext context = SSLContext.getInstance("TLSv1.2"); context.init(keyManagers, trustManagers, null); SSLSocketFactory sslFactory =context.getSocketFactory(); returnsslFactory; } private final class DefaultTrustManager implementsX509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throwsCertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throwsCertificateException { } @Override publicX509Certificate[] getAcceptedIssuers() { return newX509Certificate[]{}; } } }