Введение: почему URLConnection — это must know для Java-разработчика
Вы когда-нибудь задумывались, как ваш любимый браузер или мобильное приложение общается с сервером? Волшебство скрывается в простых, но мощных HTTP-запросах. И в Java для этого есть свой «швейцарский нож» — класс java.net.URLConnection.
Несмотря на то, что в Java 11 появился новый модульный HttpClient, тысячи разработчиков по всему миру продолжают использовать старый добрый URLConnection. Почему? Во-первых, это legacy-код, который нужно поддерживать. Во-вторых, он простой и не требует сторонних библиотек. А в-третьих, понимание того, как работают HTTP-запросы на низком уровне, делает вас настоящим профи.
В этой статье мы не просто скопируем ответ со Stack Overflow. Мы разберем два подхода к работе с URLConnection и сравним их с современным HttpClient. Вы узнаете, как отправлять GET и POST запросы, обрабатывать ошибки, устанавливать заголовки и читать ответы сервера. Поехали!
Что такое java.net.URLConnection и зачем он нужен?
Класс java.net.URLConnection — это абстрактный класс, который представляет собой активное соединение с ресурсом, указанным в URL. Простыми словами: это мостик между вашим Java-приложением и сервером в интернете. Он умеет:
- Открывать соединение с сервером
- Отправлять данные (GET, POST, PUT, DELETE)
- Читать ответ сервера
- Управлять заголовками запроса и ответа
- Работать с куками
Но есть нюанс: URLConnection не делает ничего сам. Он лишь предоставляет механизм. Всю магию делают его подклассы — например, HttpURLConnection для работы с HTTP.
Подход 1: Классический способ с HttpURLConnection (проверено временем)
Этот метод использовали наши отцы-основатели Java-программирования. Он надежен, но требует ручной работы. Давайте разберем его на примере GET-запроса.
Пример 1: GET-запрос с обработкой ответа
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class GetRequestExample {
public static void main(String[] args) throws Exception {
// 1. Создаем URL объект
URL url = new URL("https://api.github.com/users/octocat");
// 2. Открываем соединение
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 3. Настраиваем запрос
connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
// 4. Проверяем код ответа
int responseCode = connection.getResponseCode();
System.out.println("Response Code: " + responseCode);
// 5. Читаем тело ответа
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println("Response Body: " + response.toString());
} else {
System.out.println("GET request failed");
}
// 6. Закрываем соединение
connection.disconnect();
}
}
Разбор кода:
setRequestMethod— задает HTTP-метод (GET, POST, PUT, DELETE)setRequestProperty— устанавливает заголовки (User-Agent, Content-Type и т.д.)getResponseCode()— получает код состояния HTTP (200, 404, 500)getInputStream()— читает тело ответа сервераdisconnect()— закрывает соединение
Пример 2: POST-запрос с отправкой данных
А теперь усложним задачу. Допустим, нужно отправить JSON на сервер. Для этого используем POST-запрос.
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class PostRequestExample {
public static void main(String[] args) throws Exception {
URL url = new URL("https://jsonplaceholder.typicode.com/posts");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Настройка POST-запроса
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; utf-8");
connection.setRequestProperty("Accept", "application/json");
connection.setDoOutput(true); // Включаем возможность отправки данных
// Тело запроса (JSON)
String jsonInputString = "{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}";
// Отправляем данные
try (OutputStream os = connection.getOutputStream()) {
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
// Читаем ответ
int responseCode = connection.getResponseCode();
System.out.println("Response Code: " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream(), "utf-8"));
StringBuilder response = new StringBuilder();
String responseLine;
while ((responseLine = in.readLine()) != null) {
response.append(responseLine.trim());
}
System.out.println("Response Body: " + response.toString());
connection.disconnect();
}
}
Ключевые моменты:
setDoOutput(true)— обязательно для отправки данных (POST, PUT)getOutputStream()— используется для записи тела запроса- Всегда указывайте
Content-Type, чтобы сервер знал, как интерпретировать данные
Подход 2: Современный HttpClient (Java 11+)
Начиная с Java 11, в стандартной библиотеке появился java.net.http.HttpClient. Он более гибкий, поддерживает асинхронные запросы и не требует ручного управления потоками. Сравним с классикой.
GET-запрос с HttpClient
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class ModernGetExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.github.com/users/octocat"))
.header("User-Agent", "Mozilla/5.0")
.GET()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response Code: " + response.statusCode());
System.out.println("Response Body: " + response.body());
}
}
POST-запрос с HttpClient
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class ModernPostExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String json = "{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI