工具篇:apache-httpClient 和 jdk11-HttpClient的使用

关注公众号,一起交流,微信搜一搜: 潜行前行 HttpClient (apache)

apache HttpClient 是 java项目里 较为常用的组件之一;对接外部服务时,各个商家提供的接口是各式各样的,有自己的要求,因此要定制对应的请求客户端。httpClient是一个不错的选择

apache HttpClient 实现了 HTTP 1.0 和 HTTP 1.1。支持 HTTP 全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)

GET, POST 的实现是继承 HttpRequestBase,HttpRequestBase 实现 HttpUriRequest,HttpUriRequest 继承 HttpRequest;GET, POST 方法对应 java 类的 HttpGet 和 HttpPost

支持 TLS,SSL 的 HTTPS。支持多线程操作

基于阻塞的 I/0 实现,也就是说使用 HttpClient 的线程会被阻塞

头部信息设置

HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/app"); httpPost.addHeader("Accept", "application/json"); httpPost.addHeader("Content-type","application/json; charset=utf-8");

证书信息设置

private static SSLContext getSslContext() throws Exception { //自身私钥 KeyStore identityKeyStore = KeyStore.getInstance("jks"); FileInputStream identityKeyStoreFile = new FileInputStream("/root/myServer.jks"); identityKeyStore.load(identityKeyStoreFile, "password1".toCharArray()); //服务端信任证书 KeyStore trustKeyStore = KeyStore.getInstance("jks"); FileInputStream trustKeyStoreFile = new FileInputStream("/root/trustKeyStore.jks"); trustKeyStore.load(trustKeyStoreFile, "password".toCharArray()); //构建SSLContexts return SSLContexts.custom() .loadKeyMaterial(identityKeyStore, "password1".toCharArray()) // load identity keystore .loadTrustMaterial(trustKeyStore, null) // load trust keystore .build(); } public static void postWithSSL(String url, String jsonBody) throws Exception { SSLContext sslContext = getSslContext(); SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory( sslContext, new String[]{"TLSv1.2", "TLSv1.1", "TLSv1"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); CloseableHttpClient client = HttpClients.custom() .setSSLSocketFactory(sslConnectionSocketFactory) .build(); /** // HttpClients 产生的 client 都共用相同的证书秘钥 Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.INSTANCE) .register("https", new SSLConnectionSocketFactory(sslcontext)) .build(); HttpClients.custom().setConnectionManager(connManager); */ .... }

缓存 cookie 设置

//自定义 cookie CookieStore cookieStore = new BasicCookieStore(); BasicClientCookie cookie = new BasicClientCookie("csc", "lwl"); cookieStore.addCookie(cookie); // 从上一次请求获取 HttpPost httppost = ... DefaultHttpClient httpclient = new DefaultHttpClient(); HttpResponse response = httpclient.execute(httppost); CookieStore cookiestore=httpclient.getCookieStore(); // DefaultHttpClient 使用 cookie HttpPost httppost2 = ... DefaultHttpClient httpclient2 = new DefaultHttpClient(); httpclient2.setCookieStore(cookiestore); response = httpclient2.execute(httppost2);

RequestConfig 的使用

RequestConfig defaultRequestConfig = RequestConfig.custom() .setConnectTimeout(5000) .setSocketTimeout(5000) .setConnectionRequestTimeout(5000) .setRedirectsEnabled(true) .build(); //使用 CloseableHttpClient httpclient = HttpClients.custom() .setDefaultRequestConfig(defaultRequestConfig) .build();

HttpEntity 是对《请求或者响应》对象的封装,具体实现类有

BasicHttpEntity,InputStreamEntity:操作对象是数据流

BufferedHttpEntity:带缓冲区的 HttpEntity,其他HttpEntity的包装类,将内容存入一缓存区 可以重复读

FileEntity:文件对应的Entity FileEntity entity = new FileEntity(new File(""), "application/java-achive");

StringEntity:字符串 Entity。一般用 json ,text/plain,text/xml 类型的post请求

UrlEncodedFormEntity,一般用于 application/x-www-form-urlencoded 类型的post请求

HttpContext:它是 Http 请求上下文类,如果是同一个上下文,则两次请求间可以共享这个上线文的信息。虽然 HttpClient 本身就具备维护cookies的功能,但 HttpContext 的好处是在于多个 HttpClient 实例之间可以共享 HttpContext

一些建议

1 释放资源:读取完响应后,我们需要尽快释放response本身和响应实体本身的流来对资源进行回收

2 有时可能需要多次读取返回的响应内容,将响应内容进行缓冲。最简单的方法是用BufferedHttpEntity 类包装原始实体。这会让原始实体的内容被读入内存缓冲区

CloseableHttpResponse response = ... HttpEntity entity = new BufferedHttpEntity(response.getEntity());

3 HttpClient 的线程安全:使用同一个HttpClient的实例即可做到线程安全,因为 HttpClient 内部就有一个池化机制,支持多线程

4 EntityUtils.toString(entity) : 把内容转成字符串

CloseableHttpClient 是 HttpClient 的子类。mvn 引入 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.5</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.5.5</version> </dependency> HttpClient 的API HttpResponse execute(HttpUriRequest request) HttpResponse execute(HttpUriRequest request, HttpContext context) HttpResponse execute(HttpHost target, HttpRequest request) HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler) <T> T execute(HttpHost target,HttpRequest request, ResponseHandler<? extends T> responseHandler) <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) get 请求 CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet("http://localhost:8080/content/lwl"); CloseableHttpResponse httpResponse = httpClient.execute(httpGet); HttpEntity httpEntity = httpResponse.getEntity(); System.out.println(EntityUtils.toString(httpEntity));// 输出请求结果 httpResponse.close(); post 请求 CloseableHttpClient httpclient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost("https://www.baidu.com"); ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("username", "csc")); params.add(new BasicNameValuePair("password", "lwl")); httpPost.setEntity(new UrlEncodedFormEntity(params)); CloseableHttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); System.out.println(EntityUtils.toString(httpEntity));// 输出请求结果 httpResponse.close(); 文件上传 CloseableHttpClient httpClient = HttpClientBuilder.create().build(); HttpPost httpPost = new HttpPost("http://localhost:8080/lwl/upload"); MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create(); File file1 = new File("C:\\Users\\csc\\Desktop\\data.jpg"); // 第一个文件 multipartEntityBuilder.addBinaryBody("files", file1); File file2 = new File("C:\\Users\\csc\\Desktop\\头像.jpg"); // 第二个文件 // 为避免中文乱码问题,可以对文件名 urlDecode multipartEntityBuilder.addBinaryBody("files", file2, ContentType.DEFAULT_BINARY, URLEncoder.encode(file2.getName(), "utf-8")); // 其它参数 multipartEntityBuilder.addTextBody("name", "lwl", ContentType.create("text/plain", Charset.forName("UTF-8"))); HttpEntity httpEntity = multipartEntityBuilder.build(); httpPost.setEntity(httpEntity); CloseableHttpResponse response = httpClient.execute(httpPost); HttpEntity responseEntity = response.getEntity(); System.out.println(response.getStatusLine()); response.close(); HttpClient (jdk11)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzjxzy.html