前言
在jdk版本之前,jdk自带的http请求,大致只有用HttpURLConnection实现的http请求,但是jdk11之后,有了一个新特性,那就是jdk自带了一个新的http特性,能用它更好的发起http请求了
HttpCilent简介
jdk11自带的HttpClient位于java.net.http包下,里面实现了诸多的方法和功能,以下一一举例子
实例化HttpClient
实例化HttpClient类可以直接使用以下方法
HttpClient client = HttpClient.newBuilder().build();
当然,其自带了许多方法 (1)version方法
HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1)
.build();
指定是使用http1.1还是http2
(2)连接超时时间
HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1)
.connectTimeout(Duration.ofMillis(2000))
.build();
(3)指定线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1)
.connectTimeout(Duration.ofMillis(2000))
.executor(executorService)
.build();
当然,不推荐使用jdk自带的线程池策略,使用时,请使用自定义的线程池
(4)代理
ExecutorService executorService = Executors.newFixedThreadPool(10);
HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1)
.connectTimeout(Duration.ofMillis(2000))
.executor(executorService)
.proxy(ProxySelector.of(new InetSocketAddress("test.hello.cn", 8080)))
.build();
(5)重定向
ExecutorService executorService = Executors.newFixedThreadPool(10);
HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1)
.connectTimeout(Duration.ofMillis(2000))
.executor(executorService)
.proxy(ProxySelector.of(new InetSocketAddress("test.hello.cn", 8080)))
.followRedirects(HttpClient.Redirect.ALWAYS)
.build();
默认是不重定向
(6)其他的还有SSL,认证或者cookie,这里就不赘述了
使用HttpClient发送http请求
Get请求
HttpClient client = HttpClient.newBuilder().build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:9008/getData"))
.timeout(Duration.ofMinutes(2))
.GET()
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
log.info("返回值为:{{}}", response.body());
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
post发送json请求
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private Long id;
private String name;
}
发送请求
HttpClient client = HttpClient.newBuilder().build();
Student student = Student.builder().id(1L).name("aaa").build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:9008/save"))
.timeout(Duration.ofMinutes(2))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(JSON.toJSONString(student)))
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
log.info("返回值为:{{}}", response.body());
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
发送delete请求
HttpClient client = HttpClient.newBuilder().build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:9008/deleteById?id=1"))
.timeout(Duration.ofMinutes(2))
.DELETE()
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
log.info("返回值为:{{}}", response.body());
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
发送表单请求
HttpClient httpClient = HttpClient.newBuilder().build();
Map<Object, Object> data = new HashMap<>(16);
data.put("userName", "admin");
data.put("password", "123456");
HttpRequest request = HttpRequest.newBuilder()
.POST(ofFormData(data))
.uri(URI.create("http://LOCALHOST:9008/testForm1"))
.setHeader("token", "aaaa")
.header("Content-Type", "application/x-www-form-urlencoded")
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
public static HttpRequest.BodyPublisher ofFormData(Map<Object, Object> data) {
var builder = new StringBuilder();
for (Map.Entry<Object, Object> entry : data.entrySet()) {
if (builder.length() > 0) {
builder.append("&");
}
builder.append(URLEncoder.encode(entry.getKey().toString(), StandardCharsets.UTF_8));
builder.append("=");
builder.append(URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8));
}
return HttpRequest.BodyPublishers.ofString(builder.toString());
}
put请求发送
HttpClient httpClient = HttpClient.newBuilder().build();
Student student = Student.builder().id(1L).name("aaa").build();
HttpRequest request = HttpRequest.newBuilder()
.PUT(HttpRequest.BodyPublishers.ofString(JSON.toJSONString(student)))
.uri(URI.create("http://localhost:9008/update"))
.setHeader("token", "aaaa")
.build();
CompletableFuture<HttpResponse<String>> response =
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString());
String result = response.thenApply(HttpResponse::body).get(5, TimeUnit.SECONDS);
log.info("result的值为:{{}}", result);
发送异步请求
HttpClient httpClient = HttpClient.newBuilder().build();
HttpRequest request = HttpRequest.newBuilder()
.GET()
.uri(URI.create("http://localhost:9008/user/findById"))
.setHeader("token", "aaaa")
.build();
CompletableFuture<HttpResponse<String>> response =
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString());
String result = response.thenApply(HttpResponse::body).get(5, TimeUnit.SECONDS);
log.info("result的值为:{{}}", result);
总结
jdk11之后,用jdk11实现http请求相比之前自带的http请求,方便快捷,但是相对Java的开放性来说,已经有其他大神封装好了一堆http请求工具,具体怎么选择工具类,全凭自己用的上手以及工具类的方便性,能否大大提高自己的开发效率