更新日期:2022/03/24
愿你如阳光,明媚不忧伤。
1. Header 消息头2. RequestConfig 请求配置3. HttpContext HTTP 执行上下文4. HttpRequestRetryHandler 请求重试处理5. HttpEntity 内容实体
5.1 streamed(流式)5.2 self-contained(自包含式)5.3 wrapping(包装式) 6. UrlEncodedFormEntity HTML 表单7. MultipartEntityBuilder 上传文件
7.1 流文件上传 8. ResponseHandler 响应处理程序
友情链接 【HTTP 通信】HttpClient 基础篇
1. Header 消息头
HTTP 标头字段是客户端程序和服务器在每个 HTTP 请求和响应中发送和接收的字符串列表。这些标头通常对最终用户不可见,仅由服务器和客户端应用程序处理或记录。
*************************************************************************
public static void main(String[] args) throws IOException {
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.addHeader("Cache-Control", "max-age=3600");
response.addHeader("Date", "Mon, 21 Mar 2022 08:12:31 GMT");
HeaderIterator it = response.headerIterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
【Console】--------------------------------------------------------------
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Cache-Control: max-age=3600
Date: Mon, 21 Mar 2022 08:12:31 GMT
*************************************************************************
2. RequestConfig 请求配置
RequestConfig.java
用于获取和配置一些外部的网络环境,它下面有一个嵌套类 RequestConfig.Builder。
参考文献 https://www.cnblogs.com/chengxiansheng/p/13232686.html
***************************************************************** // 是否期望能够继续:主要用于发送首先请求标头,以查看服务器是否允许(接受)请求。如果服务器显示OK,则发送100-continue,客户端继续请求正文。否则,服务器响应417(期望失败) private boolean expectContinueEnabled; // 设置代理 IP private HttpHost proxy; // InetAddress 类的对象用于 IP 地址和域名,取决于它是用主机名构造的,还是已经完成了反向主机名解析。"ouseki/192.168.2.6" private InetAddress localAddress; // 是否启用陈旧连接检查 private boolean staleConnectionCheckEnabled = false; // cookie 规格 private String cookieSpec; // 是否启用重定向 private boolean redirectsEnabled = true; // 是否允许相对重定向 private boolean relativeRedirectsAllowed = true; // 是否允许循环重定向 private boolean circularRedirectsAllowed; // 设置最大重定向 private int maxRedirects = 50; // 是否启用身份验证 private boolean authenticationEnabled = true; // 目标首选身份验证方案 private CollectiontargetPreferredAuthSchemes; // 代理首选身份验证方案 private Collection proxyPreferredAuthSchemes; // 设置连接请求超时 private int connectionRequestTimeout = -1; // 设置连接超时 private int connectTimeout = -1; // 设置 socket 读写超时 private int socketTimeout = -1; // 是否启用内容压缩 private boolean contentCompressionEnabled = true; // 是否标准化 Uri private boolean normalizeUri = true; *****************************************************************
RequestConfig 应用实例
*****************************************************************
public class TestHttpClient {
public static void main(String[] args) throws IOException {
// 新建一个RequestConfig
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(1)
.setSocketTimeout(1)
.setConnectionRequestTimeout(1)
.build();
// 这个超时可以设置为客户端级别,作为所有请求的默认值
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultRequestConfig(defaultRequestConfig)
.build();
System.out.println(httpclient.execute(new HttpGet("http://localhost:8080/")));
}
}
【Console】------------------------------------------------------
17:52:30.792 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {}->http://localhost:8080][total available: 0; route allocated: 0 of 2; total allocated: 0 of 20]
Exception in thread "main" org.apache.http.conn.ConnectTimeoutException: Connect to localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: connect timed out
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:151)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at com.ouseki.itgodroad.controller.TestHttpClient.main(TestHttpClient.java:50)
Caused by: java.net.SocketTimeoutException: connect timed out
at java.base/java.net.PlainSocketImpl.waitForConnect(Native Method)
at java.base/java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:107)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
at java.base/java.net.Socket.connect(Socket.java:608)
at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:75)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
... 10 more
*****************************************************************
3. HttpContext HTTP 执行上下文
HttpContext 功能与 java.util.Map
HttpClientContext.java
可以使用 HttpClientContext 这个适配器类来简化操作上下文状态。
*************************************************************************
public class TestHttpClient extends LogBean {
public static void main(String[] args) throws IOException {
HttpContext context=new BasicHttpContext();
context.setAttribute(HttpClientContext.HTTP_TARGET_HOST,new HttpHost("localhost", 8080, "http"));
context.setAttribute(HttpClientContext.HTTP_ROUTE,new HttpRoute(new HttpHost("localhost", 80, "http")));
HttpClientContext clientContext = HttpClientContext.adapt(context);
System.out.println(clientContext.getTargetHost());
System.out.println(clientContext.getHttpRoute());
}
}
【Console】--------------------------------------------------------------
http://localhost:8080
{}->http://localhost:80
*************************************************************************
发送端
第二次请求没有携带参数,但还是读取到了内容,因为使用了相同的上下文,第一次请求过后,就将 jsessionid 保存起来了。
*************************************************************************
public class TestHttpClient extends LogBean {
public static void main(String[] args) throws IOException {
HttpContext httpContext = new BasicHttpContext();
HttpClientContext httpClientContext = HttpClientContext.adapt(httpContext);
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://localhost:8080/ITGodRoad/testHttpContext.do");
// 第一次请求,设置请求参数
List formParams = new ArrayList<>();
formParams.add(new BasicNamevaluePair("name", "ouseki"));
formParams.add(new BasicNamevaluePair("collect", "人世间"));
formParams.add(new BasicNamevaluePair("collect", "ITGodRoad"));
httpPost.setEntity(new UrlEncodedFormEntity(formParams));
CloseableHttpResponse response = null;
try {
response = httpclient.execute(httpPost, httpClientContext);
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity);
System.out.println("第一次请求响应:" + result);
}
} finally {
assert response != null;
response.close();
}
System.out.println("=================第二次请求====================");
// 重新创建一个 HttpPost 对象,但是此次该对象中不设置请求参数
httpPost = new HttpPost("http://localhost:8080/ITGodRoad/testHttpContext.do");
try {
response = httpclient.execute(httpPost, httpClientContext);
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity);
System.out.println("第二次请求响应:" + result);
}
} finally {
response.close();
}
}
}
【Console】--------------------------------------------------------------
第一次请求响应:login success!B503DAD69B10A4BACBEF44B037F1518E
=================第二次请求====================
第二次请求响应:Having been login ouseki B503DAD69B10A4BACBEF44B037F1518E
*************************************************************************
目标服务端
*************************************************************************
@RequestMapping("/testHttpContext.do")
public void testHttpContext(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
String jsessionid = session.getId();
// 从 session 中获取 name
String name = (String) session.getAttribute("name");
String result;
if (name == null) {
// 从请求参数中获取 name 的值
name = request.getParameter("name");
session.setAttribute("name", name);
result = "login success!" + jsessionid;
} else {
result = "Having been login " + name + "t" + jsessionid;
}
// 将 result 内容写回到 response 响应体中
ServletOutputStream outputStream = null;
PrintWriter printWriter = null;
try {
outputStream = response.getOutputStream();
printWriter = new PrintWriter(outputStream);
printWriter.write(result);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (printWriter != null) {
printWriter.close();
}
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
*************************************************************************
4. HttpRequestRetryHandler 请求重试处理
默认情况下 HttpClient 尝试从 I/O exception 中自动恢复。默认的自动恢复机制只局限于少数已知的安全的异常。
- HttpClient 不会试图从任何逻辑或 HTTP 协议错误(衍生自 HttpException 类)中恢复。HttpClient 将自动重试那些被认为是幂等的方法。为了保证 HTTP 传输层的安全性,系统必须保证应用层中的 HTTP 方法是幂等的。HttpClient 将自动重试那些因传输异常而失败但是 HTTP 请求仍然会被发送到目标服务器的方法。即请求还没有完全被发送到服务器端
createHttpclientWithRetryHandler.java
为了使自定义异常恢复机制有效,实现了HttpRequestRetryHandler接口
*************************************************************************
public static HttpClient createHttpclientWithRetryHandler() {
HttpRequestRetryHandler customRetryHandler = (exception, executionCount, context) -> {
if (executionCount >= 5) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof InterruptedIOException) {
// Timeout
return false;
}
if (exception instanceof UnknownHostException) {
// Unknown host
return false;
}
if (exception instanceof SSLException) {
// SSL handshake exception
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
boolean idempotent = request instanceof HttpEntityEnclosingRequest;
if (!idempotent) {
// Retry if the request is considered idempotent
return true;
}
return false;
};
return HttpClients.custom()
.setRetryHandler(customRetryHandler)
.build();
}
*************************************************************************
5. HttpEntity 内容实体
HTTP 消息可以携带与其相关联的请求或响应的内容实体(它们是可选的)。
使用了实体的请求被称为封闭实体请求。当执行一次封闭实体请求或者是请求成功后,响应体被当做返回结果发回客户端的时候创建实体。
HttpClient 根据其内容来源分为三种类型的实体:streamed(流式)、self-contained(自包含式)、wrapping(包装式)
HttpEntity.java
HashApple.txt 是序列化后的二进制(字节)文件,需要反序列化才能正确显示其内容,乱码是对的。
*************************************************************************
public class TestHttpClient extends LogBean {
public static void main(String[] args) throws IOException {
FileEntity fileEntity = new FileEntity(new File("E:\HashApple.txt"), ContentType.DEFAULT_BINARY);
// 告知此实体是否依赖于基础流。
System.out.println("isStreamingt" + fileEntity.isStreaming());
// 告知实体是否能够多次生成其数据。
System.out.println("isRepeatablet" + fileEntity.isRepeatable());
System.out.println("isChunkedt" + fileEntity.isChunked());
InputStream content = fileEntity.getContent();
System.out.println("getContentt" + new String(content.readAllBytes()));
// 也可以调用 EntityUtils 工具类中方法(默认字符编码为 ISO_8859_1)
System.out.println("getContentt" + EntityUtils.toString(fileEntity));
System.out.println("getContentTypet" + fileEntity.getContentType());
System.out.println("getContentLengtht" + fileEntity.getContentLength());
System.out.println("getContentEncodingt" + fileEntity.getContentEncoding());
}
}
【Console】--------------------------------------------------------------
isStreaming false
isRepeatable true
isChunked false
getContent �� sr )com.ouseki.itgodroad.controller.HashApple L colort Ljava/lang/String;L gramt Ljava/lang/Double;L shapeq ~ xpt redsr java.lang.Double���J)k� D valuexr java.lang.Number������ xp@i��Q�t circle
getContent ¬í sr )com.ouseki.itgodroad.controller.HashApple L colort Ljava/lang/String;L gramt Ljava/lang/Double;L shapeq ~ xpt redsr java.lang.Double€³ÂJ)kû D valuexr java.lang.Number†¬•”à‹ xp@i
¸Qìt circle
getContentType Content-Type: application/octet-stream
getContentLength 227
getContentEncoding null
*************************************************************************
5.1 streamed(流式)
内容是从流中接收的,或者是动态生成的。流式实体是不可重复生成的。
*************************************************************************
InputStream is = new ByteArrayInputStream("streamed".getBytes());
BasicHttpEntity basicHttpEntity = new BasicHttpEntity();
basicHttpEntity.setContent(is);
InputStreamEntity inputStreamEntity = new InputStreamEntity(is);
SerializableEntity serializableEntity = new SerializableEntity("ouseki",true);
*************************************************************************
5.2 self-contained(自包含式)
内容在内存中或通过独立于连接或其他实体的方式获得。自包含实体可以重复生成(意味着它的内容可以被多次读取)。这种类型的实体将主要被用于封闭 HTTP 请求。
*************************************************************************
ByteArrayEntity byteArrayEntity = new ByteArrayEntity("self-contained".getBytes());
FileEntity fileEntity = new FileEntity(new File("E:\exercise.gif"), ContentType.IMAGE_GIF);
String str = "self-contained";
StringEntity stringEntity2 = new StringEntity(str, StandardCharsets.UTF_8);
*************************************************************************
5.3 wrapping(包装式)
内容是从另一个实体获取的。
*************************************************************************
HttpEntity httpEntity = new StringEntity("wrapping");
BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(httpEntity);
DecompressingEntity decompressingEntity = new DecompressingEntity(httpEntity,GZIPInputStreamFactory.getInstance());
GzipCompressingEntity gzipCompressingEntity = new GzipCompressingEntity(httpEntity);
*************************************************************************
6. UrlEncodedFormEntity HTML 表单
许多应用程序需要模拟一个提交 HTML 表单的过程,HttpClient 提供了实体类 UrlEncodedFormEntity 它使用 URL 编码来编码参数,生成如下的内容:param1=value1¶m2=value2
发送端
*************************************************************************
public class TestHttpClient extends LogBean {
public static void main(String[] args) throws IOException {
List formParams = new ArrayList<>();
formParams.add(new BasicNamevaluePair("name", "ouseki"));
formParams.add(new BasicNamevaluePair("collect", "人世间"));
formParams.add(new BasicNamevaluePair("collect", "ITGodRoad"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, StandardCharsets.UTF_8);
HttpPost httppost = new HttpPost("http://localhost:8080/ITGodRoad/testUrlEncodedFormEntity.do");
httppost.setEntity(entity);
CloseableHttpClient httpclient = HttpClientBuilder.create().build();
CloseableHttpResponse response = httpclient.execute(httppost);
HttpEntity responseEntity = response.getEntity();
if (responseEntity != null) {
System.out.println("HTTPS响应内容长度为:" + responseEntity.getContentLength());
String responseStr = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
System.out.println("HTTPS响应内容为:" + responseStr);
}
}
}
【Console】--------------------------------------------------------------
HTTPS响应内容长度为:47
10:07:19.257 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection [id: 0][route: {}->http://localhost:8080] can be kept alive for 20.0 seconds
10:07:19.257 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 0
10:07:19.257 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {}->http://localhost:8080][total available: 1; route allocated: 1 of 2; total allocated: 1 of 20]
HTTPS响应内容为:name : [ouseki]collect : [人世间, ITGodRoad]
*************************************************************************
目标服务端
如果后端响应返回的中文乱码,肯定是编码问题,有两种解决方案:
1.修改注解:produces = { “text/plain;charset=utf-8” }
2.配置拦截器并设置 response.setContentType(“application/json;charset=utf-8”);
*************************************************************************
@RestController
public class Test {
@RequestMapping(value = "/testUrlEncodedFormEntity.do", produces = { "text/plain;charset=utf-8" })
public String test(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
Map parameterMap = request.getParameterMap();
StringBuilder stringBuilder = new StringBuilder();
for (String key : parameterMap.keySet()) {
String[] value = parameterMap.get(key);
stringBuilder.append(key).append(" : ").append(Arrays.toString(value));
}
return stringBuilder.toString();
}
}
*************************************************************************
7. MultipartEntityBuilder 上传文件
pom.xml
即便不引入 httpmime 依赖,也是能传输文件的,不过功能不够强大。
org.apache.httpcomponents httpmime 4.5.13
发送端
*************************************************************************
public class TestHttpClient extends LogBean {
public static void main(String[] args) {
List params = new ArrayList<>();
params.add(new BasicNamevaluePair("name", "ouseki"));
params.add(new BasicNamevaluePair("age", "25"));
URI uri = null;
try {
uri = new URIBuilder().setScheme("http").setHost("localhost")
.setPort(8080).setPath("/ITGodRoad/testDoUpload.do")
.addParameters(params)
.build();
} catch (URISyntaxException e) {
e.printStackTrace();
}
doUpload(uri);
}
.........................................................................
public static void doUpload(URI uri) {
String filesKey = "files";
File file = new File("E:\uploadFiles");
File[] files = file.listFiles();
assert files != null;
ClientCustomSSLUtil.doUpload(uri, filesKey, files);
}
}
*************************************************************************
public class ClientCustomSSLUtil {
public static void doUpload(URI uri, String filesKey, File[] files) {
CloseableHttpClient httpclient = HttpClientBuilder.create().build();
HttpPost httppost = new HttpPost(uri);
CloseableHttpResponse response = null;
try {
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
for (File file : files) {
multipartEntityBuilder.addBinaryBody(filesKey, file, ContentType.DEFAULT_BINARY, URLEncoder.encode(file.getName(), StandardCharsets.UTF_8));
}
HttpEntity httpEntity = multipartEntityBuilder.build();
httppost.setEntity(httpEntity);
response = httpclient.execute(httppost);
HttpEntity responseEntity = response.getEntity();
System.out.println(("HTTPS 响应状态为:" + response.getStatusLine()));
if (responseEntity != null) {
System.out.println("HTTPS 响应内容长度为:" + responseEntity.getContentLength());
String responseStr = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
System.out.println("HTTPS 响应内容为:" + responseStr);
}
} catch (ParseException | IOException e) {
e.printStackTrace();
} finally {
try {
assert response != null;
httpclient.close();
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
【Console】--------------------------------------------------------------
HTTPS 响应状态为:HTTP/1.1 200
HTTPS 响应内容长度为:200
HTTPS 响应内容为:ouseki25
文件信息
文件名:cat.jpeg 文件大小:40kb 文件类型:application/octet-stream
文件信息
文件名:HashApple.txt 文件大小:0kb 文件类型:application/octet-stream
*************************************************************************
目标服务端
*************************************************************************
@RequestMapping(value = "/testUrlEncodedFormEntity.do", produces = { "text/plain;charset=utf-8" }, method = RequestMethod.POST)
public String testDoUpload(@RequestParam("name") String name, @RequestParam("age") String age,
@RequestParam("files") List multipartFilesList) throws UnsupportedEncodingException {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(name).append(age);
String fileName;
for (MultipartFile file : multipartFilesList) {
stringBuilder.append("n文件信息n");
fileName = file.getOriginalFilename();
if (fileName == null) {
continue;
}
fileName = URLDecoder.decode(fileName, Constant.UTF_8);
stringBuilder.append("t文件名:").append(fileName);
stringBuilder.append("t文件大小:").append(file.getSize() / 1024).append("kb");
stringBuilder.append("t文件类型:").append(file.getContentType());
}
return stringBuilder.toString();
}
*************************************************************************
7.1 流文件上传
发送端
*************************************************************************
public class TestHttpClient extends LogBean {
public static void main(String[] args) {
List params = new ArrayList<>();
params.add(new BasicNamevaluePair("name", "ouseki"));
params.add(new BasicNamevaluePair("age", "25"));
URI uri = null;
try {
uri = new URIBuilder().setScheme("http").setHost("localhost")
.setPort(8080).setPath("/ITGodRoad/testDoUploadStream.do")
.addParameters(params)
.build();
} catch (URISyntaxException e) {
e.printStackTrace();
}
doUploadStream(uri);
}
.........................................................................
public static void doUploadStream(URI uri) {
InputStream inputStream = new ByteArrayInputStream("流文件上传".getBytes());
CloseableHttpClient httpclient = HttpClientBuilder.create().build();
HttpPost httppost = new HttpPost(uri);
CloseableHttpResponse response = null;
try {
InputStreamEntity ise = new InputStreamEntity(inputStream);
httppost.setEntity(ise);
response = httpclient.execute(httppost);
HttpEntity responseEntity = response.getEntity();
System.out.println("HTTPS 响应状态为:" + response.getStatusLine());
if (responseEntity != null) {
System.out.println("HTTPS 响应内容长度为:" + responseEntity.getContentLength());
String responseStr = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
System.out.println("HTTPS 响应内容为:" + responseStr);
}
} catch (ParseException | IOException e) {
e.printStackTrace();
} finally {
try {
assert response != null;
httpclient.close();
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
【Console】--------------------------------------------------------------
HTTPS 响应状态为:HTTP/1.1 200
HTTPS 响应内容长度为:50
HTTPS 响应内容为:ouseki25输入流中的数据为:流文件上传
*************************************************************************
目标服务端
*************************************************************************
@RequestMapping(value = "/testDoUploadStream.do", produces = { "text/plain;charset=utf-8" }, method = RequestMethod.POST)
public String testDoUploadStream(@RequestParam("name") String name, @RequestParam("age") String age, InputStream inputStream) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(name).append(age).append("输入流中的数据为:");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, Constant.UTF_8));
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
return stringBuilder.toString();
}
*************************************************************************
8. ResponseHandler 响应处理程序
处理响应最简单方便的方式是使用 ResponseHandler 接口,它包含了 handleResponse(HttpResponse response) 方法。
这个方法彻底的解决了用户对于连接管理的困扰。当使用 ResponseHandler 接口时, 无论是否请求执行成功或引发异常,HttpClient 都会自动关闭来确保释放的连接返回到连接管理器。
*************************************************************************
public class TestHttpClient extends LogBean {
public static void main(String[] args) throws IOException {
System.out.println(customResponseHandler());
}
.........................................................................
public static String customResponseHandler() throws IOException {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("http://localhost:8080/ITGodRoad/testUrlEncodedFormEntity.do");
ResponseHandler responseHandler = (response) -> {
StatusLine statusLine = response.getStatusLine();
HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(
statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
if (entity == null) {
throw new ClientProtocolException("Response contains no content");
}
return "请求访问成功";
};
return httpclient.execute(httppost, responseHandler);
}
}
【Console】--------------------------------------------------------------
请求访问成功
*************************************************************************



