Какие основные способы выполнения HTTP-запросов в Java?

Ответ

В Java существует несколько стандартных и библиотечных способов выполнения HTTP-запросов, от низкоуровневых до высокоуровневых абстракций.

1. Java 11+ HttpClient (Стандартный, асинхронный/синхронный) Современный API, поддерживающий HTTP/2 и WebSocket.

// Синхронный GET-запрос
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.example.com/users"))
      .header("Accept", "application/json")
      .GET()
      .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println("Body: " + response.body());

// Асинхронный POST-запрос с JSON
String json = "{"name":"John"}";
HttpRequest postRequest = HttpRequest.newBuilder()
      .uri(URI.create("https://api.example.com/users"))
      .header("Content-Type", "application/json")
      .POST(HttpRequest.BodyPublishers.ofString(json))
      .build();
client.sendAsync(postRequest, HttpResponse.BodyHandlers.ofString())
      .thenApply(HttpResponse::body)
      .thenAccept(System.out::println);

2. Spring RestTemplate (Синхронный, устаревший в пользу WebClient)

RestTemplate restTemplate = new RestTemplate();
String url = "https://api.example.com/users/{id}";
User user = restTemplate.getForObject(url, User.class, 1); // GET
ResponseEntity<User> response = restTemplate.getForEntity(url, User.class, 1);

// POST
User newUser = new User("Jane");
User createdUser = restTemplate.postForObject("https://api.example.com/users", newUser, User.class);

3. Spring WebClient (Реактивный, асинхронный, рекомендованный)

WebClient client = WebClient.create("https://api.example.com");
Mono<User> userMono = client.get()
      .uri("/users/{id}", 1)
      .header("Authorization", "Bearer token")
      .retrieve()
      .bodyToMono(User.class);

userMono.subscribe(user -> System.out.println(user.getName()));

// POST с телом
Mono<User> createdUser = client.post()
      .uri("/users")
      .contentType(MediaType.APPLICATION_JSON)
      .bodyValue(new User("Bob"))
      .retrieve()
      .bodyToMono(User.class);

4. Библиотеки третьих сторон

  • Apache HttpClient: Мощный и гибкий клиент.
  • OkHttp: Эффективный клиент от Square, часто используется с Retrofit.
  • Retrofit + OkHttp: Типобезопасный REST-клиент для Android и Java, генерирует реализации интерфейсов.

Критерии выбора:

  • Синхронность/Асинхронность: HttpClient/WebClient для неблокирующих вызовов.
  • Экосистема: В Spring-проектах предпочтителен WebClient.
  • Сложность: HttpClient требует больше boilerplate-кода, WebClient и RestTemplate предоставляют более высокоуровневый API.

Ответ 18+ 🔞

О, смотри-ка, какие у нас тут способы по интернету полазить, как будто в 2024 году без этого можно! Ну ладно, раз уж ты спросил, разложу по полочкам, но только без этой скучной академической хуйни.

Первый, самый свежий корешок — HttpClient из Java 11+ Это типа наш новый, модный, причёсанный инструмент. Поддерживает HTTP/2, может и синхронно, и асинхронно — красота, ёпта!

// Делаем запрос по-старинке, ждём ответа как дурачки
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.example.com/users"))
      .header("Accept", "application/json")
      .GET()
      .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Статус: " + response.statusCode()); // Надеемся, что не 404, а то пиздец
System.out.println("Тело: " + response.body());

// А вот это уже по-взрослому, асинхронно, чтобы не тормозить
String json = "{"name":"John"}";
HttpRequest postRequest = HttpRequest.newBuilder()
      .uri(URI.create("https://api.example.com/users"))
      .header("Content-Type", "application/json")
      .POST(HttpRequest.BodyPublishers.ofString(json))
      .build();
client.sendAsync(postRequest, HttpResponse.BodyHandlers.ofString())
      .thenApply(HttpResponse::body)
      .thenAccept(System.out::println); // Ответ придёт когда-нибудь потом, а мы пока чай попьём

Второй, старый дед — Spring RestTemplate Этот уже на пенсию собирается, но в старых проектах его дохуя. Синхронный, простой, как валенок.

RestTemplate restTemplate = new RestTemplate();
String url = "https://api.example.com/users/{id}";
User user = restTemplate.getForObject(url, User.class, 1); // Тыкаем и получаем юзера
ResponseEntity<User> response = restTemplate.getForEntity(url, User.class, 1); // А тут ещё и статус прилетает

// Хочешь создать что-то? POST тебе в помощь!
User newUser = new User("Jane");
User createdUser = restTemplate.postForObject("https://api.example.com/users", newUser, User.class);

Третий, реактивный красавчик — Spring WebClient Вот это уже серьёзно. Если твой проект на Spring и ты не хочешь, чтобы всё вставало колом, пока ждёшь ответа от какого-нибудь долбанного API — это твой выбор.

WebClient client = WebClient.create("https://api.example.com");
Mono<User> userMono = client.get()
      .uri("/users/{id}", 1)
      .header("Authorization", "Bearer token") // Без токена сейчас нихуя не получишь
      .retrieve()
      .bodyToMono(User.class); // Обещание, что юзер когда-нибудь будет

userMono.subscribe(user -> System.out.println(user.getName())); // А вот когда будет — обрадуемся

// Создаём нового чувака
Mono<User> createdUser = client.post()
      .uri("/users")
      .contentType(MediaType.APPLICATION_JSON)
      .bodyValue(new User("Bob"))
      .retrieve()
      .bodyToMono(User.class);

Четвёртые, всякие левые библиотеки с улицы Тут, блядь, выбор как в борделе:

  • Apache HttpClient — старый, мощный, на всём готовом. Конфигурировать можно до посинения.
  • OkHttp — от ребят из Square, быстрый, умный, часто под капотом у других.
  • Retrofit + OkHttp — это вообще магия. Описываешь интерфейс, а он тебе реализацию на лету генерит. Красота, ядрёна вошь!

Так какого хуя выбрать?

  • Если пишешь на чистой Java 11+ и не хочешь тащить лишние зависимости — HttpClient твой бро.
  • Если проект на Spring и ты не вчера родился — бери WebClient. RestTemplate уже в утиль пора, честно.
  • Нужна максимальная гибкость и контроль, как у сапёра? Apache HttpClient или OkHttp.
  • Делаешь под Андроид или любишь, когда всё красиво и типобезопасно? Retrofit — твоя палочка-выручалочка.

Вот и вся наука, блядь. Главное — не усложняй там, где не надо. А то накрутишь такого, что потом сам разбираться будешь, как в дебрях Амазонки.