一、HttpClient5
1、概述
- HttpClient5 是 Apache HttpComponents 项目中的一个重要组件,专门用于发送 HTTP 请求和处理 HTTP 响应
2、HttpClient5 引入
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
</dependency>
二、HttpClient5 基本使用
1、普通 GET 请求
(1)Server
@GetMapping("/testGet")
public String testGet() {
return "testGet Hello World";
}
(2)client
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpGet httpGet = new HttpGet("http://127.0.0.1:9999/test/testGet");
String result = httpClient.execute(httpGet, classicHttpResponse -> EntityUtils.toString(classicHttpResponse.getEntity()));
System.out.println("请求成功,结果为:" + result);
} catch (IOException e) {
e.printStackTrace();
}
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
请求成功,结果为:testGet Hello World
2、普通带参 Get 请求
(1)Server
@GetMapping("/testGetCarryData")
public String testGetCarryData(@RequestParam("str") String str) {
return "testGetCarryData " + str;
}
(2)Client
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpGet httpGet = new HttpGet("http://127.0.0.1:9999/test/testGetCarryData?str=12345");
String result = httpClient.execute(httpGet, classicHttpResponse -> EntityUtils.toString(classicHttpResponse.getEntity()));
System.out.println("请求成功,结果为:" + result);
} catch (IOException e) {
e.printStackTrace();
}
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
URI uri = new URIBuilder("http://127.0.0.1:9999/test/testGetCarryData")
.addParameter("str", "12345")
.build();
HttpGet httpGet = new HttpGet(uri);
String result = httpClient.execute(httpGet, classicHttpResponse -> EntityUtils.toString(classicHttpResponse.getEntity()));
System.out.println("请求成功,结果为:" + result);
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
}
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
请求成功,结果为:testGetCarryData 12345
3、RESTFul GET 请求
(1)Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
class User {
private int id;
private String name;
private int age;
}
(2)Server
@GetMapping("/testRestful/{id}")
public User testGetRestful(@PathVariable Integer id) {
HashMap<Integer, User> userMap = new HashMap<>();
userMap.put(1, new User(1, "jack", 10));
userMap.put(2, new User(2, "tom", 20));
userMap.put(3, new User(3, "smith", 30));
return userMap.get(id);
}
(3)Client
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpGet httpGet = new HttpGet("http://127.0.0.1:9999/test/testGetRestful/1");
User user = httpClient.execute(httpGet, classicHttpResponse -> {
String str = EntityUtils.toString(classicHttpResponse.getEntity());
return JSON.parseObject(str, User.class);
});
System.out.println("请求成功,结果为:" + user);
} catch (IOException e) {
e.printStackTrace();
}
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
请求成功,结果为:User(id=1, name=jack, age=10)
4、普通 POST 请求
(1)Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
class User {
private int id;
private String name;
private int age;
}
(2)Server
@PostMapping("/testPost")
public User testPost(@RequestBody User user) {
HashMap<Integer, User> userMap = new HashMap<>();
userMap.put(1, new User(1, "jack", 10));
userMap.put(2, new User(2, "tom", 20));
userMap.put(3, new User(3, "smith", 30));
return userMap.get(user.getId());
}
(3)Client
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
User user = new User();
user.setId(1);
HttpPost httpPost = new HttpPost("http://127.0.0.1:9999/test/testPost");
StringEntity stringEntity = new StringEntity(JSON.toJSONString(user), ContentType.APPLICATION_JSON);
httpPost.setEntity(stringEntity);
User result = httpClient.execute(httpPost, classicHttpResponse -> {
String str = EntityUtils.toString(classicHttpResponse.getEntity());
return JSON.parseObject(str, User.class);
});
System.out.println("请求成功,结果为:" + result);
} catch (IOException e) {
e.printStackTrace();
}
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
User(id=1, name=null, age=0)
三、HttpClient5 异常请求
1、404 请求
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpGet httpGet = new HttpGet("http://127.0.0.1:9999/test/testGet12345");
CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpGet);
String result = EntityUtils.toString(closeableHttpResponse.getEntity());
if (closeableHttpResponse.getCode() == 200) {
System.out.println("请求成功,结果为:" + result);
} else {
System.out.println("请求失败:" + result);
}
} catch (IOException | ParseException e) {
e.printStackTrace();
System.out.println("请求失败:" + e.getMessage());
}
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
请求失败:{"timestamp":"2024-08-23T06:01:10.209+00:00","status":404,"error":"Not Found","path":"/test/testGet12345"}
2、超时请求
(1)Server
@GetMapping("/testTimeout")
public String testTimeout() {
try {
Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "testTimeout Hello World";
}
(2)Client
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(Timeout.ofMilliseconds(5000L))
.setConnectionRequestTimeout(Timeout.ofMilliseconds(5000L))
.setResponseTimeout(Timeout.ofMilliseconds(5000L))
.build();
CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(config).build();
try {
HttpGet httpGet = new HttpGet("http://127.0.0.1:9999/test/testTimeout");
CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpGet);
String result = EntityUtils.toString(closeableHttpResponse.getEntity());
if (closeableHttpResponse.getCode() == 200) {
System.out.println("请求成功,结果为:" + result);
} else {
System.out.println("请求失败:" + result);
}
} catch (IOException | ParseException e) {
e.printStackTrace();
System.out.println("请求失败:" + e.getMessage());
}
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
java.net.SocketTimeoutException: Read timed out
请求失败:Read timed out
四、HttpClient5 扩展
1、下载图片
(1)Server
server:
port: 9999
spring:
mvc:
static-path-pattern: /file/download/**
web:
resources:
static-locations: file:D:/fileUpload/
(2)Client
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpGet httpGet = new HttpGet("http://127.0.0.1:9999/file/download/1.png");
byte[] result = httpClient.execute(httpGet, classicHttpResponse -> EntityUtils.toByteArray(classicHttpResponse.getEntity()));
System.out.println("请求成功");
System.out.println("result length is " + result.length);
} catch (IOException e) {
e.printStackTrace();
}
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
请求成功
result length is 846049
2、忽略 SSL 证书
try {
TrustStrategy acceptingTrustStrategy = (x509Certificates, s) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build();
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
CloseableHttpClient httpClient = httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager).build();
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
e.printStackTrace();
}
3、跟随重定向响应
(1)Server
@GetMapping("/testRedirect")
public ResponseEntity testRedirect() {
return ResponseEntity.status(HttpStatus.SEE_OTHER)
.header("Location", "http://127.0.0.1:9999/test/testGet")
.build();
}
(2)Client
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpGet httpGet = new HttpGet("http://127.0.0.1:9999/test/testRedirect");
String result = httpClient.execute(httpGet, classicHttpResponse -> EntityUtils.toString(classicHttpResponse.getEntity()));
System.out.println("请求成功,结果为:" + result);
} catch (IOException e) {
e.printStackTrace();
}
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
请求成功,结果为:testGet Hello World
4、跟随重定向响应图片流
(1)Server
server:
port: 9999
spring:
mvc:
static-path-pattern: /file/download/**
web:
resources:
static-locations: file:D:/fileUpload/
@GetMapping("/testRedirect2Image")
public ResponseEntity testRedirect2Image() {
return ResponseEntity.status(HttpStatus.SEE_OTHER)
.header("Location", "http://127.0.0.1:9999/file/download/1.png")
.build();
}
(2)Client
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpGet httpGet = new HttpGet("http://127.0.0.1:9999/test/testRedirect2Image");
byte[] result = httpClient.execute(httpGet, classicHttpResponse -> EntityUtils.toByteArray(classicHttpResponse.getEntity()));
System.out.println("请求成功");
System.out.println("result length is " + result.length);
} catch (IOException e) {
e.printStackTrace();
}
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
请求成功
result length is 846049