1.1 Giới thiệu về HttpClient

Bắt đầu với JDK 11, các nhà phát triển nền tảng Java đã thêm một công cụ mới mạnh mẽ vào JDK để thực hiện các yêu cầu http, đó là java.net.http. Nó chứa bốn lớp chính:

  • HttpClient
  • HttpRequest
  • HttpResponse
  • ổ cắm web

Đây là những lớp rất mạnh cho phép bạn thực hiện tất cả các loại yêu cầu có thể bằng cách sử dụng HTTP, HTTP/2WebSocket.

Ngoài ra, bạn có thể sử dụng các lớp này để thực hiện cả yêu cầu http đồng bộ và không đồng bộ.

Tạo một yêu cầu http bao gồm các phần sau:

  1. Tạo một đối tượngHttpClient
  2. Tạo một đối tượngHttpRequest
  3. Gửi yêu cầu bằng phương thức send()hoặcsendAsync()
  4. xử lý phản hồiHttpResponse

Một ví dụ về yêu cầu như vậy:


 HttpClient client = HttpClient.newBuilder()
        .version(Version.HTTP_1_1)
        .followRedirects(Redirect.NORMAL)
        .connectTimeout(Duration.ofSeconds(20))
        .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
        .authenticator(Authenticator.getDefault())
        .build();
 
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body()); 

1.2 Cách tiếp cận khai báo

Trong ví dụ trên, bạn thấy một ví dụ về cái gọi là phương pháp khai báo để viết mã. Chúng ta hãy xem phần đầu tiên của ví dụ:


 HttpClient client = HttpClient.newBuilder()
.version(Version.HTTP_1_1)
.followRedirects(Redirect.NORMAL)
.connectTimeout(Duration.ofSeconds(20))
.proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
.authenticator(Authenticator.getDefault())
.build();

Mã này trông như thế nào được viết theo phong cách cổ điển:


HttpClient client = HttpClient.new();
client.setVersion(Version.HTTP_1_1);
client.setFollowRedirects(Redirect.NORMAL);
client.setConnectTimeout(Duration.ofSeconds(20));
client.setProxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)));
client.setAuthenticator(Authenticator.getDefault());

Khi sử dụng phương pháp khai báo trong mã, có hai điều thay đổi. Thứ nhất , tất cả các phương thức của lớp HttpClient đều trả về đối tượng của riêng chúng , điều này cho phép bạn tổ chức mã dưới dạng chuỗi.

Mã cổ điển:

HttpClient client = HttpClient.new();
client.setVersion(Version.HTTP_1_1);
client.setFollowRedirects(Redirect.NORMAL);
client.setConnectTimeout(Duration.ofSeconds(20));
client.setAuthenticator(Authenticator.getDefault());
Là một chuỗi:

HttpClient client = HttpClient.new() .setVersion(Version.HTTP_1_1) .setFollowRedirects(Redirect.NORMAL). setConnectTimeout(Duration.ofSeconds(20)) .setAuthenticator(Authenticator.getDefault());
Chúng tôi chuyển từng phương thức sang một dòng riêng biệt (đây là một câu lệnh dài)

HttpClient client = HttpClient.new()
.setVersion(Version.HTTP_1_1)
.setFollowRedirects(Redirect.NORMAL)
.setConnectTimeout(Duration.ofSeconds(20))
.setAuthenticator(Authenticator.getDefault());

Thứ hai , tiền tố được loại bỏ khỏi các phương thức set, cho phép bạn viết mã thậm chí còn gọn hơn:

Đã từng là

HttpClient client = HttpClient.new()
.setVersion(Version.HTTP_1_1)
.setFollowRedirects(Redirect.NORMAL)
.setConnectTimeout(Duration.ofSeconds(20))
.setAuthenticator(Authenticator.getDefault());

Nó đã trở thành

HttpClient client = HttpClient.new()
.version(Version.HTTP_1_1)
.followRedirects(Redirect.NORMAL)
.connectTimeout(Duration.ofSeconds(20))
.authenticator(Authenticator.getDefault());
    

Mã như vậy dễ đọc hơn, mặc dù khó viết hơn.

Và một điểm quan trọng nữa. Trong ví dụ này, mẫu Builder đã được sử dụng. Có những tình huống mà việc tạo một đối tượng là một quá trình phức tạp. Do đó, họ muốn chính thức hóa nó: nó bắt đầu bằng một lệnh gọi phương thức có điều kiện begin()và kết thúc bằng một lệnh gọi phương thức có điều kiện end().

Trong ví dụ mà chúng ta đã phân tích, phương thức HttpClient.newBuilder()trả về một đối tượng HttpClient.Builder(đây là một lớp tiện ích bên trong của lớp HttpClient). Tất cả các phương thức của loại version()được gọi chỉ trên đối tượng dịch vụ này. Chà, lời gọi của phương thức build()đánh dấu sự kết thúc của việc xây dựng đối tượng và trả về đối tượng HttpClient.