Skip to main content

Command Palette

Search for a command to run...

Bài 8: HTTP Client API (Java 11)

Published
6 min readView as Markdown

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:

    • HttpURLConnection là 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.
  • 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.


More from this blog

hoangkim

366 posts