4.1 Phương thức send(), BodyHandlers

Bạn đã học xong cách tạo một yêu cầu http , vì vậy bạn có thể chuyển sang phần quan trọng nhất - gửi yêu cầu này. Trong trường hợp đơn giản nhất, điều này rất dễ thực hiện:


HttpRequest request = HttpRequest.newBuilder(new URI("https://codegym.cc")).build();
 
   HttpClient client = HttpClient.newBuilder()
        .version(Version.HTTP_1_1)
        .build();
 
   HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
   System.out.println(response.statusCode() );
   System.out.println(response.body() ); 

BodyHandlersđây là những gì? Bạn nghĩ sao? Bạn đã gửi yêu cầu, nghĩa là bạn sẽ nhận được câu trả lời - http response. Và phản hồi này có thể có response body: một chuỗi, một tệp, một mảng byte, một InputStream.

Vâng, vâng, đúng vậy. Giống như khi tạo một yêu cầu, bạn cần chỉ định loại response bodyphản hồi. Tổng cộng có thể có 8 miếng:

  • BodyHandlers.ofByteArray
  • BodyHandlers.ofString
  • BodyHandlers.ofFile
  • BodyHandlers.discarding
  • BodyHandlers.replacing
  • BodyHandlers.ofLines
  • BodyHandlers.fromLineSubscriber

Tùy thuộc vào loại BodyHandlersbạn đã truyền cho phương thức send(), nó sẽ trả về loại kết quả như vậy. Ví dụ:

// response body is ignored
HttpResponse<Void> response = client.send(request, BodyHandlers.discarding());
// response body is a string
 HttpResponse<String>response = client.send(request, BodyHandlers.ofString());
// response body is a file
HttpResponse<Path> response = client.send(request, BodyHandlers.ofFile(Paths.get("readme.txt")));
// response body is an InputStream
HttpResponse<InputStream> response = client.send(request, BodyHandlers.ofInputStream());

Nếu một tệp sẽ được gửi cho bạn dưới dạng phản hồi, thì BodyHandlers.ofFile()bạn cần chuyển tên của tệp cục bộ cho phương thức, nơi nó sẽ được lưu bởi đối tượng HttpClient.

4.2 phương thức followRedirects()

301Ngoài ra, khi gửi yêu cầu, bạn có thể chỉ định HttpClient nên làm gì nếu máy chủ gửi hoặc 302(chuyển hướng tạm thời hoặc vĩnh viễn) trong phản hồi . Hãy tưởng tượng rằng máy chủ đã gửi một mã 302và bạn cần: theo dõi tình huống này, lấy một URL mới từ phản hồi và gửi yêu cầu đến địa chỉ mới.

Tôi không muốn làm điều này lắm, đặc biệt khi xem xét rằng tình huống này là phổ biến và từ lâu đã được tự động hóa trong tất cả các ứng dụng khách http. Cũng trong HttpClient này, bạn chỉ cần chỉ định chế độ chuyển hướng nào bạn chọn khi gửi yêu cầu.

HttpResponse response = HttpClient.newBuilder()
  .followRedirects( HttpClient.Redirect.ALWAYS )
  .build()
  .send(request, BodyHandlers.ofString());

Chỉ có 3 tùy chọn để chuyển hướng:

  • LUÔN - luôn luôn;
  • KHÔNG BAO GIỜ - không bao giờ;
  • BÌNH THƯỜNG - luôn luôn, ngoại trừ HTTPS -> HTTP.

Như bạn có thể thấy, không có nhiều tùy chọn ở đây, nhưng có khả năng tùy chỉnh luôn tốt hơn là không có.

4.4 Phương thức proxy()

Có một vài tùy chọn hữu ích hơn, nhưng không được sử dụng thường xuyên. Bạn không cần chúng chính xác cho đến khi bạn cần chúng :)

Cái đầu tiên là proxy. Trong cuộc sống bình thường, bạn không thường xuyên gặp phải chúng, nhưng nhiều tập đoàn lớn có một hệ thống bảo mật lưu lượng truy cập Internet phức tạp bên trong chúng, và do đó có nhiều cài đặt proxy khác nhau.

Tất nhiên, phần mềm của bạn, vốn sẽ hoạt động ở đâu đó trong lòng của một tập đoàn như vậy, một ngày nào đó sẽ gặp phải thực tế là nó sẽ cần sử dụng proxy. Do đó, thật tốt khi một tùy chọn như vậy cũng có ở đây.

Thiết lập proxy rất đơn giản - một ví dụ:

HttpResponse<String> response = HttpClient.newBuilder()
  .proxy( ProxySelector.getDefault())
  .build()
  .send(request, BodyHandlers.ofString());

Proxy mặc định đã được chọn ở đây, nhưng bạn có thể muốn đặt proxy của riêng mình:

HttpResponse response = HttpClient.newBuilder()
  .proxy(ProxySelector.of(new InetSocketAddress("proxy.microsoft.com", 80)))
  .build()
  .send(request, BodyHandlers.ofString());

Chúng tôi sẽ không xem xét chính xác cách làm việc với proxy, vì điều này không nằm trong phạm vi của khóa học này.

trình xác thực 4.5()

Và một điểm quan trọng nữa. Giao thức HTTP hỗ trợ xác thực. Ngay ở cấp độ giao thức.

Bây giờ phương pháp này gần như không được sử dụng, nhưng khoảng 20 năm trước, nó đã phổ biến. Yêu cầu http trông như thế này:

http://username@example.com/

Hoặc thậm chí như thế này:

http://username:password@example.com/

Đây không phải là thư. Đây chính xác là liên kết. Và vâng, bạn đã không nghĩ như vậy. Thông tin đăng nhập và thậm chí cả mật khẩu có thể được chỉ định trực tiếp trong yêu cầu http. Vâng, ngay cả bây giờ bạn có thể. Đó là lý do tại sao tôi viết rằng không ai thường làm điều này bây giờ. Nhưng có một khả năng như vậy.

Authenticator auth = new Authenticator() {
    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(
     "username",
        "password".toCharArray());
    }
};

HttpResponse<String> response = HttpClient.newBuilder()
  .authenticator(auth).build()
  .send(request, BodyHandlers.ofString());

Hay đấy! Bạn có biết tại sao thay vì “password"trong mã nó nói không "password".toCharArray()?

Bởi vì tham số thứ hai của hàm tạo PasswordAuthentication không phải là String, mà là CharArray.

Và tại sao tham số thứ hai không phải là String, huh CharArray?

Bởi vì tất cả mật khẩu không được phép lưu trữ dưới dạng toàn bộ chuỗi vì mục đích bảo mật, ngay cả trong ứng dụng của riêng bạn . Nghĩa là, ứng dụng của bạn trong bộ nhớ không được lưu mật khẩu dưới dạng chuỗi. Vì vậy, nếu ai đó làm ẩm bộ nhớ, mật khẩu sẽ không thể rút ra được ...

Nhưng đồng thời, mật khẩu có thể được truyền qua giao thức HTTP không an toàn trên nửa thế giới :) :) :)

Tốt. Thế giới không hoàn hảo.

Bạn có thể đọc thêm về chủ đề này tại các liên kết dưới đây:

xác thực HTTP

Hiểu xác thực HTTP