Рубрики
Без рубрики

Как отправлять HTTP-запросы на Java

Автор оригинала: David Landup.

Вступление

Протокол передачи гипертекста (HTTP)-это протокол прикладного уровня, который, без преувеличения, в значительной степени является основой просмотра Интернета в том виде, в каком мы его знаем.

Он используется для передачи документов гипермедиа между клиентом и сервером и является неотъемлемой частью каждого отдельного веб-приложения, включая любые API, использующие архитектуру REST.

Это позволяет браузеру взаимодействовать с сервером, отправляя запросы на определенные документы, будь то HTML-документы (возвращаемые в виде страниц, которые мы видим) или гипермедиа (изображения, видео и т.д.), Которые отображаются на страницах.

Как Работает HTTP?

Когда мы решаем посетить веб-сайт, за кулисами происходит то, что наш компьютер генерирует и отправляет запрос на сервер, на котором размещен веб-сайт.

HTTP-запрос может выглядеть примерно так:

GET /tag/java/ HTTP/1.1
Host: stackabuse.com
Accept: */*
User-Agent: Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion

Здесь мы запрашиваем , чтобы сервер отправил обратно страницу по URL-адресу stackabuse.com/tag/java/ использование HTTP версии 1.1.

Сервер должен ответить примерно так:

HTTP/1.1 200 OK
Date: Fri, 01 Feb 2019 22:07:06 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=dd40ff971a6cefddc4855e028541f79581549051234; expires=Sat, 01-Feb-20 22:07:06 GMT; path=/; domain=.stackabuse.com; HttpOnly; Secure
...

За этим следует ответный орган :





    
    
    java - Page 1 - Stack Abuse
    
    


Затем тело ответа будет отображено в нашем браузере, и нас встретит страница!

Помимо кода состояния HTTP/1.1 200 OK , который мы получили в качестве ответа, есть еще несколько других, с которыми вы, вероятно, сталкивались в своей повседневной жизни:

  • 1xx : Любой статус, начинающийся с “1”, является информационным статусом. Запрос получен и находится в стадии обработки.
  • 2xx : Любой статус, начинающийся с “2”, означает, что запрос был успешным . В большинстве случаев это 200 ОК , что просто означает, что все прошло гладко.
  • 3xx : Любой статус, начинающийся с “3”, означает, что пользователь должен быть перенаправлен для завершения действия.
  • 4xx : Любой статус, начинающийся с “4”, указывает на ошибку клиента . Самый печально известный из них – 404 Не найден , обычно из-за неправильного запроса или синтаксиса. Наряду с этим, есть 400 Плохих запросов , 401 Несанкционированный и 403 Запрещенных . Эти коды статуса являются наиболее распространенными, и их существует широкий спектр.
  • 5xx : Любое состояние, начинающееся с “5”, указывает на ошибку сервера .

полный список кодов состояния HTTP довольно длинный, хотя неплохо бы его просмотреть.

Отправка запросов с помощью HttpURLConnection

HttpURLConnection – это базовый класс Java для обработки HTTP-запросов и ответов.

Использование HttpURLConnection идеально подходит для простых HTTP-запросов, хотя, если вы хотите проще добавлять такие вещи, как заголовки или аутентификацию, вам будет проще полагаться на другие библиотеки, такие как Apache Commons. ССЫЛКА НА СТАТЬЮ APACHE ЗДЕСЬ

Самый простой способ создать экземпляр объекта HttpURLConnection – это использовать объект URL :

URL url = new URL("https://www.stackabuse.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();

Типы запросов

Теперь, когда наш Экземпляр HttpURLConnection существует, мы можем определить для него тип HTTP-запроса:

// For a GET request
connection.setRequestMethod("GET");

// For a POST request
connection.setRequestMethod("POST");

// For a HEAD request
connection.setRequestMethod("HEAD");

// For a OPTIONS request
connection.setRequestMethod("OPTIONS");

// For a PUT request
connection.setRequestMethod("PUT");

// For a DELETE request
connection.setRequestMethod("DELETE");

// For a TRACE request
connection.setRequestMethod("TRACE");

Хотя в большинстве случаев вы будете использовать только GET , POST и DELETE .

Параметры запроса

В некоторых случаях мы хотели бы отправить HTTP-запрос с определенными параметрами запроса, такими как www.youtube.com/watch?v=dQw4w9WgXcQ .

Чтобы достичь этого, мы обычно придумываем способ сопоставить эти значения. Иногда люди определяют свои собственные классы для хранения этих значений с помощью простого Хэш-карты все будет в порядке:

Map params = new HashMap<>();
params.put("v", "dQw4w9WgXcQ");

Git Essentials

Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!

Теперь, когда мы сопоставили наши параметры, нам нужно сделать пару вещей, чтобы подготовить их к нашему запросу:

  • Создайте параметр в строковом формате. Мы будем использовать StringBuilder , так как он идеально подходит для объединения, которое мы будем выполнять
  • Используйте класс URLEncoder для кодирования наших параметров
  • Преобразуйте данные в байты, так как наш Поток вывода данных , который запускает запрос, ожидает массив типа байт

Примечание : Если вы не уверены, зачем нам нужно кодировать ваш URL – адрес-это потому, что некоторые символы могут иметь особое значение в URL-адресах. Такие персонажи, как “/”, “.”, “#” , и “?” может изменить запрос, поэтому, если они присутствуют, нам нужно закодировать их таким образом, чтобы это не повлияло на интерпретацию URL-адреса.

Давайте реализуем пункты из списка:

// Instantiate a requestData object to store our data
StringBuilder requestData = new StringBuilder();

for (Map.Entry param : params.entrySet()) {
    if (requestData.length() != 0) {
        requestData.append('&');
    }
    // Encode the parameter based on the parameter map we've defined
    // and append the values from the map to form a single parameter
    requestData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
    requestData.append('=');
    requestData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}

// Convert the requestData into bytes 
byte[] requestDataByes = requestData.toString().getBytes("UTF-8");

И, таким образом, наш параметр готов к использованию в запросе.

Заголовки запросов

Если вы хотите добавить заголовок к запросу, это так же просто, как:

connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Content-Length", String.valueOf(requestDataBytes.length));

И если вы хотите прочитать заголовок запроса:

String contentType = connection.getHeaderField("Content-Type");

Тайм-ауты

Еще одна особенность HttpURLConnection предложения устанавливает тайм-ауты . Мы можем определить интервалы ожидания для чтения или подключения:

connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);

Интервалы, как обычно, определяются в миллисекундах.

Так, например, время ожидания соединения истекает, если оно не может быть установлено в течение 10 секунд. Аналогично, это также приведет к тайм-ауту, если данные не могут быть считаны из соединения в течение 10 секунд.

ОТПРАВИТЬ запрос

С вашим запросом все готово, мы можем продолжить и отправить СООБЩЕНИЕ запрос:

// Set the doOutput flag to true
connection.setDoOutput(true);

// Get the output stream of the connection instance
// and add the parameter to the request
try (DataOutputStream writer = new DataOutputStream(connection.getOutputStream())) {
    writer.write(postDataBytes);

    // Always flush and close
    writer.flush();
    writer.close();
}

Здесь мы отправляем postDataBytes в наш POST запрос, который представляет собой массив байтов. Ознакомьтесь с демонстрацией ниже для получения более подробной информации о том, как это создать.

ПОЛУЧИТЬ запрос

Как только мы отправляем запрос POST , мы обычно хотим что-то сделать (или, по крайней мере, просмотреть) ответ.

Запросы GET предназначены только для извлечения данных, поэтому давайте продолжим и получим ответ:

// To store our response
StringBuilder content;

// Get the input stream of the connection
try (BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
    String line;
    content = new StringBuilder();
    while ((line = input.readLine()) != null) {
        // Append each line of the response and separate them
        content.append(line);
        content.append(System.lineSeparator());
    }
} finally {
    connection.disconnect();
}

// Output the content to the console
System.out.println(content.toString());

На этом этапе мы можем извлечь множество различных видов информации из соединения :

// Returns the value of the content-type header field
connection.getContentType();

// Returns an unmodifiable Map of the header fields
connection.getHeaderFields();

// Gets the status code from an HTTP response message
connection.getResponseCode();

// Gets the HTTP response message returned along with the response code from a server
connection.getResponseMessage();

// Returns the error stream if the connection failed but the server sent useful data nonetheless
connection.getErrorStream();

// ...etc

Демонстрация

Вот как очень простое приложение сгенерирует запрос POST , отправит его, а затем прочитает ответ:

public static void main(String[] args) throws MalformedURLException, ProtocolException, IOException {
    URL url = new URL("https://www.youtube.com");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

    connection.setRequestMethod("POST");
    Map params = new HashMap<>();
    params.put("v", "dQw4w9WgXcQ");

    StringBuilder postData = new StringBuilder();
    for (Map.Entry param : params.entrySet()) {
        if (postData.length() != 0) {
            postData.append('&');
        }
        postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
        postData.append('=');
        postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
    }

    byte[] postDataBytes = postData.toString().getBytes("UTF-8");
    connection.setDoOutput(true);
    try (DataOutputStream writer = new DataOutputStream(connection.getOutputStream())) {
        writer.write(postDataBytes);
        writer.flush();
        writer.close();

        StringBuilder content;

        try (BufferedReader in = new BufferedReader(
                new InputStreamReader(connection.getInputStream()))) {
        String line;
        content = new StringBuilder();
           while ((line = in.readLine()) != null) {
                content.append(line);
                content.append(System.lineSeparator());
            }
        }
        System.out.println(content.toString());
    } finally {
        connection.disconnect();
    }
}

Запуск этого фрагмента кода, безусловно, достаточно, чтобы получить исходный код страницы, которую мы указали для получения:





  

Вывод

Протокол передачи гипертекста (HTTP)-это протокол прикладного уровня, который, без преувеличения, является очень большим и важным компонентом для интернет-приложений.

HttpURLConnection – это базовый класс Java для обработки HTTP-запросов и ответов.

Использование HttpURLConnection идеально подходит для простых HTTP-запросов, хотя, если вы хотите создавать более сложные HTTP-запросы с заголовками или аутентификацией, у вас будет гораздо более простой опыт работы с такими библиотеками, как Apache Commons. ССЫЛКА НА СТАТЬЮ APACHE ЗДЕСЬ