Как использовать java.net.URLConnection для отправки и обработки HTTP запросов?
Правильная работа с HttpURLConnection
Ваша главная ошибка — использование абстрактного класса URLConnection вместо HttpURLConnection. Для HTTP необходимо явно приводить соединение к этому типу. Также важно соблюдать порядок действий: сначала настройка, потом запись, потом чтение.
Базовый шаблон для POST запроса
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.*;
public class HttpPostExample {
public static void main(String[] args) throws Exception {
URL url = new URL("http://example.com/api/data");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 1. Настройка соединения
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("User-Agent", "Mozilla/5.0");
conn.setDoOutput(true); // Разрешаем запись
conn.setDoInput(true); // Разрешаем чтение
// 2. Отправка данных
String params = "param1=value1¶m2=value2";
try (OutputStream os = conn.getOutputStream()) {
byte[] input = params.getBytes("utf-8");
os.write(input, 0, input.length);
}
// 3. Проверка кода ответа
int responseCode = conn.getResponseCode();
System.out.println("Response Code: " + responseCode);
// 4. Чтение ответа (учитываем ошибки)
BufferedReader reader;
if (responseCode >= 200 && responseCode < 300) {
reader = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "utf-8"));
} else {
reader = new BufferedReader(
new InputStreamReader(conn.getErrorStream(), "utf-8"));
}
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line.trim());
}
reader.close();
System.out.println("Response: " + response.toString());
conn.disconnect();
}
}
GET запрос
public class HttpGetExample {
public static void main(String[] args) throws Exception {
URL url = new URL("http://example.com/api/data?param1=value1");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
int responseCode = conn.getResponseCode();
System.out.println("Response Code: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = reader.readLine()) != null) {
response.append(inputLine);
}
reader.close();
System.out.println(response.toString());
} else {
System.out.println("GET request failed");
}
conn.disconnect();
}
}
Важные моменты
- Порядок действий строгий: сначала настройка (setRequestMethod, setRequestProperty), потом setDoOutput, потом getOutputStream, потом getInputStream.
- Нельзя смешивать чтение и запись: после вызова getInputStream() запись в OutputStream запрещена.
- Всегда закрывайте потоки в блоке try-with-resources или finally.
- Обрабатывайте коды ошибок: используйте getErrorStream() для кодов 4xx и 5xx.
- Устанавливайте User-Agent — многие серверы блокируют запросы без этого заголовка.
Работа с JSON
conn.setRequestProperty("Content-Type", "application/json; utf-8");
conn.setRequestProperty("Accept", "application/json");
String jsonInput = "{\"key\":\"value\"}";
try (OutputStream os = conn.getOutputStream()) {
byte[] input = jsonInput.getBytes("utf-8");
os.write(input, 0, input.length);
}
Этот подход работает для большинства HTTP API. Для более сложных сценариев (redirects, cookies, multipart) рекомендую использовать HttpClient из Java 11+.
Альтернатива: использование Apache HttpClient (если нужна гибкость)
Стандартный URLConnection хорош для простых запросов, но для сложных сценариев (прокси, keep-alive, автоматические редиректы) лучше использовать библиотеку Apache HttpClient.
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.*;
import org.apache.http.entity.*;
import org.apache.http.util.*;
public class ApacheHttpExample {
public static void main(String[] args) throws Exception {
try (CloseableHttpClient client = HttpClients.createDefault()) {
// POST запрос
HttpPost post = new HttpPost("http://example.com/api/data");
post.setHeader("Content-Type", "application/json");
post.setEntity(new StringEntity("{\"key\":\"value\"}"));
try (CloseableHttpResponse response = client.execute(post)) {
String content = EntityUtils.toString(response.getEntity());
System.out.println("Status: " + response.getStatusLine().getStatusCode());
System.out.println("Response: " + content);
}
// GET запрос
HttpGet get = new HttpGet("http://example.com/api/data?param=value");
try (CloseableHttpResponse response = client.execute(get)) {
String content = EntityUtils.toString(response.getEntity());
System.out.println(content);
}
}
}
}
Преимущества Apache HttpClient:
- Автоматическое управление соединениями (пул соединений).
- Поддержка всех HTTP методов (PUT, DELETE, PATCH).
- Встроенная обработка редиректов и куки.
- Потокобезопасность.
Недостаток: нужно добавлять зависимость в Maven/Gradle. Для простых проектов достаточно стандартного HttpURLConnection.
Ответов пока нет.
Войдите чтобы оставить ответ