工具篇:apache-httpClient 和 jdk11-HttpClient的使用
2021-11-13 12:19
1241 查看
关注公众号,一起交流,微信搜一搜: 潜行前行
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
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请求
一些建议
- 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)
java.net.http.HttpClient 是 jdk11 中正式启用的一个 http 工具类(在 jdk9 的时候就已经存在),官方想要取代 HttpURLConnection 和 Apache HttpClient 等比较古老的开发工具
HttpClient 的API
//创建一个 HttpClient public static Builder newBuilder() public static HttpClient newHttpClient() // HttpClient.newBuilder().build() //webSocket协议的请求客户端的构建者 public WebSocket.Builder newWebSocketBuilder() public abstract Optional<CookieHandler> cookieHandler() // 获取 CookieHandler public abstract Optional<Duration> connectTimeout() public abstract Redirect followRedirects() public abstract Optional<ProxySelector> proxy() public abstract SSLContext sslContext() public abstract Optional<Executor> executor()
- HttpClient.Builder 的 API
//缓存cookie设置 public Builder cookieHandler(CookieHandler cookieHandler); //连接超时时间 public Builder connectTimeout(Duration duration); // 证书信息设置 public Builder sslContext(SSLContext sslContext); // SSL / TLS / DTLS连接的参数 设置 public Builder sslParameters(SSLParameters sslParameters); //涉及到异步操作用到的 线程池 public Builder executor(Executor executor); // 是否支持重定向 Redirect.SAME_PROTOCOL public Builder followRedirects(Redirect policy); // 协议版本,HTTP/1.1 还是 HTTP/2 public Builder version(HttpClient.Version version); public Builder priority(int priority); //配置代理 public Builder proxy(ProxySelector proxySelector); //认证 Authenticator.getDefault() public Builder authenticator(Authenticator authenticator);
- HttpClient 调用 API
//阻塞调用 <T> HttpResponse<T> send(HttpRequest request, HttpResponse.BodyHandler<T> responseBodyHandler) //相当于使用了多路复用I/O <T> CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest request, BodyHandler<T> responseBodyHandler) abstract <T> CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest request, BodyHandler<T> responseBodyHandler, PushPromiseHandler<T> pushPromiseHandler)
HttpRequest 构建的 API
对于请求内容可以使用 BodyPublishers 封装的函数生成
HttpResponse 的API
对于响应的解析读取可以使用 BodyHandlers 或者 BodySubscribers 封装的函数处理
get 请求
HttpRequest request = HttpRequest.newBuilder(URI.create("http://localhost:8080/content/lwl")) .GET() .timeout(Duration.ofSeconds(10)) // 设置响应超时时间 .build(); HttpClient httpClient = HttpClient.newHttpClient(); HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body());
post 请求
String data = .....// json 请求数据 HttpRequest request = HttpRequest.newBuilder(URI.create("https://www.baidu.com")) .POST(HttpRequest.BodyPublishers.ofString(data, Charset.defaultCharset())) .header("Content-Type", "application/json") //设置头部信息 .timeout(Duration.ofSeconds(10)) // 设置响应超时时间 .build(); HttpClient httpClient = HttpClient.newHttpClient(); HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body());
欢迎指正文中错误
参考文章
相关文章推荐
- Apache Common HttpClient使用之七种武器
- 使用Apache中的HttpClient的实例CloseableHttpClient的一个例子
- 使用Apache HttpClient突破J2EE站点认证
- Android Studio无法使用Apache的HttpClient
- apache httpclient 使用例子
- 使用Apache Httpclient访问Spring rest接口下载文件
- Android中使用Apache HttpClient
- 使用Apache HttpClient实现多线程下载的小例子
- 使用搜狐Sendcloud的Webapi发送邮件:Jodd和Apache Httpclient
- OkHttp的基本使用——替代Apache HttpClient
- 使用Apache HttpClient访问JSP发送GET和POST请求
- 使用java的HttpURLconnnection模拟form上传 以及apache httpClient 直接上传文件
- Apache Common HttpClient使用之七种武器
- 使用org.apache.commons.httpclient
- 使用Apache HttpClient 4.x进行异常重试
- HttpClientUtil [使用apache httpclient模拟http请求]
- 使用httpClient报错,The type org.apache.http.HttpResponse cannot be resolved
- apache httpclient 使用
- (Apache)使用HttpClient方式访问HTTP
- Android 网络应用--Apache HttpClient的使用