jdk11新特性之Http请求

998 阅读2分钟

前言

在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请求工具,具体怎么选择工具类,全凭自己用的上手以及工具类的方便性,能否大大提高自己的开发效率