Bài 8: HTTP Client API (Java 11)
Mục tiêu
Bài viết này nhằm mục đích giúp bạn hiểu và sử dụng HTTP Client API mới trong Java 11. Chúng ta sẽ xem xét các vấn đề với API cũ, các thành phần chính của HTTP Client API, các phương thức quan trọng và các ví dụ thực tế.
Nội dung
1. Giới thiệu về HTTP Client API
1.1 Vấn đề với API cũ
Hạn chế của
HttpURLConnection:HttpURLConnectionlà API cũ để thực hiện các yêu cầu HTTP. Nó phức tạp, khó sử dụng và thiếu tính năng hiện đại.Không hỗ trợ HTTP/2, không tích hợp tốt với lập trình không đồng bộ và lập trình phản ứng (reactive programming).
Ví dụ:
URL url = new URL("http://example.com"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); int responseCode = connection.getResponseCode(); InputStream responseStream = connection.getInputStream();
1.2 Mục đích và lợi ích của HTTP Client API
Mục đích:
- HTTP Client API được giới thiệu trong Java 11 để thay thế
HttpURLConnection, cung cấp một API hiện đại, dễ sử dụng và mạnh mẽ cho việc thực hiện các yêu cầu HTTP.
- HTTP Client API được giới thiệu trong Java 11 để thay thế
Lợi ích:
Hỗ trợ HTTP/1.1 và HTTP/2.
Tích hợp tốt với lập trình không đồng bộ và lập trình phản ứng.
Cung cấp các phương thức tiện lợi và rõ ràng để thực hiện các yêu cầu HTTP.
2. Các thành phần chính của HTTP Client API
2.1 HttpClient
Mục đích: Đại diện cho một HTTP client, dùng để gửi các yêu cầu HTTP.
Tạo HttpClient:
HttpClient client = HttpClient.newHttpClient();
2.2 HttpRequest
Mục đích: Đại diện cho một yêu cầu HTTP.
Tạo HttpRequest:
HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://example.com")) .GET() .build();
2.3 HttpResponse
Mục đích: Đại diện cho một phản hồi HTTP.
Xử lý HttpResponse:
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); int statusCode = response.statusCode(); String responseBody = response.body();
3. Các phương thức quan trọng của HTTP Client API
3.1 Gửi yêu cầu đồng bộ
Ví dụ:
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://example.com")) .GET() .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); int statusCode = response.statusCode(); String responseBody = response.body(); System.out.println("Status code: " + statusCode); System.out.println("Response body: " + responseBody);
3.2 Gửi yêu cầu không đồng bộ
Ví dụ:
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://example.com")) .GET() .build(); CompletableFuture<HttpResponse<String>> futureResponse = client.sendAsync(request, HttpResponse.BodyHandlers.ofString()); futureResponse.thenApply(HttpResponse::body) .thenAccept(System.out::println) .join();
3.3 Gửi yêu cầu POST
Ví dụ:
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://example.com/post")) .POST(HttpRequest.BodyPublishers.ofString("Hello, World!")) .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); int statusCode = response.statusCode(); String responseBody = response.body(); System.out.println("Status code: " + statusCode); System.out.println("Response body: " + responseBody);
3.4 Xử lý HTTP/2
Ví dụ:
HttpClient client = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_2) .build(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://http2.akamai.com/demo")) .GET() .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); int statusCode = response.statusCode(); String responseBody = response.body(); System.out.println("Status code: " + statusCode); System.out.println("Response body: " + responseBody);
3.5 Sử dụng Headers
Ví dụ:
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://example.com")) .header("User-Agent", "Java 11 HttpClient Bot") .GET() .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); int statusCode = response.statusCode(); String responseBody = response.body(); System.out.println("Status code: " + statusCode); System.out.println("Response body: " + responseBody);
3.6 Xử lý JSON
Ví dụ:
import com.fasterxml.jackson.databind.ObjectMapper; public class HttpClientExample { public static void main(String[] args) throws Exception { HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1")) .GET() .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); ObjectMapper mapper = new ObjectMapper(); Post post = mapper.readValue(response.body(), Post.class); System.out.println("Post ID: " + post.getId()); System.out.println("Title: " + post.getTitle()); } public static class Post { private int id; private String title; // Getters and setters public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } }
4. Ví dụ thực tế sử dụng HTTP Client API
4.1 Gửi yêu cầu GET và xử lý phản hồi
Ví dụ:
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://example.com")) .GET() .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); int statusCode = response.statusCode(); String responseBody = response.body(); System.out.println("Status code: " + statusCode); System.out.println("Response body: " + responseBody);
4.2 Gửi yêu cầu POST với JSON payload
Ví dụ:
import com.fasterxml.jackson.databind.ObjectMapper; public class HttpClientExample { public static void main(String[] args) throws Exception { HttpClient client = HttpClient.newHttpClient(); ObjectMapper mapper = new ObjectMapper(); Post post = new Post(); post.setTitle("Hello, World!"); String json = mapper.writeValueAsString(post); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://jsonplaceholder.typicode.com/posts")) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(json)) .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); int statusCode = response.statusCode(); String responseBody = response.body(); System.out.println("Status code: " + statusCode); System.out.println("Response body: " + responseBody); } public static class Post { private String title; // Getters and setters public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } }
4.3 Gửi yêu cầu không đồng bộ và xử lý kết quả
Ví dụ:
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://example.com")) .GET() .build(); CompletableFuture<HttpResponse<String>> futureResponse = client.sendAsync(request, HttpResponse.BodyHandlers.ofString()); futureResponse.thenApply(HttpResponse::body) .thenAccept(System.out::println) .join();
5. Thực hành với các bài
toán thực tế
5.1 Tải tệp từ URL và lưu vào tệp hệ thống
Bài toán: Tải một tệp từ URL và lưu nó vào tệp hệ thống.
Giải pháp:
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; public class FileDownloadExample { public static void main(String[] args) throws IOException, InterruptedException { HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://example.com/file.zip")) .GET() .build(); HttpResponse<byte[]> response = client.send(request, HttpResponse.BodyHandlers.ofByteArray()); Files.write(Paths.get("file.zip"), response.body(), StandardOpenOption.CREATE); System.out.println("File downloaded successfully!"); } }
5.2 Kiểm tra trạng thái của một URL
Bài toán: Kiểm tra xem một URL có hoạt động hay không bằng cách gửi yêu cầu HEAD.
Giải pháp:
import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; public class URLStatusChecker { public static void main(String[] args) throws Exception { HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://example.com")) .method("HEAD", HttpRequest.BodyPublishers.noBody()) .build(); HttpResponse<Void> response = client.send(request, HttpResponse.BodyHandlers.discarding()); int statusCode = response.statusCode(); System.out.println("Status code: " + statusCode); } }
5.3 Đăng nhập vào một dịch vụ web
Bài toán: Gửi yêu cầu POST để đăng nhập vào một dịch vụ web và lưu cookie phản hồi.
Giải pháp:
import java.net.CookieManager; import java.net.CookiePolicy; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.util.List; import java.util.Map; public class WebLoginExample { public static void main(String[] args) throws Exception { CookieManager cookieManager = new CookieManager(); cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); HttpClient client = HttpClient.newBuilder() .cookieHandler(cookieManager) .build(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://example.com/login")) .header("Content-Type", "application/x-www-form-urlencoded") .POST(HttpRequest.BodyPublishers.ofString("username=user&password=pass")) .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Status code: " + response.statusCode()); System.out.println("Response body: " + response.body()); // Lấy cookie từ phản hồi Map<String, List<String>> headers = response.headers().map(); List<String> cookies = headers.get("Set-Cookie"); if (cookies != null) { cookies.forEach(System.out::println); } } }
Kết luận
HTTP Client API trong Java 11 mang lại một cách tiếp cận hiện đại và mạnh mẽ để thực hiện các yêu cầu HTTP. Với hỗ trợ cho HTTP/2, lập trình không đồng bộ và các tính năng tiện lợi khác, HTTP Client API giúp lập trình viên thực hiện các tác vụ HTTP một cách dễ dàng và hiệu quả. Hiểu và sử dụng thành thạo HTTP Client API sẽ giúp bạn tận dụng tối đa sức mạnh của Java 11 trong việc giao tiếp với các dịch vụ web và API.