java get запрос с параметрами
Работа с сервлетами для чайников. GET / POST
В прошлой статье Создание сервлетов для чайников. Пошаговое руководство я описал, как создать сервлеты и попытался объяснить, как это работает. В этой статье мы научим наши сервлеты работать с UI через HTTP-запросы GET и POST.
На самом деле, этих запросов намного больше, но для чистоты эксперимента мы разберём только два основных.
Пометим сервлет в xml-документе web.xml:
Пишем вот такую страницу bot.jsp (пока просто копируем, потом разберём):
Эта страница выводит нам данные бота.
Отметим, что ссылка Update переводит на адрес bot?action=update содержит данные для GET-запроса.
Также, у нас будет страница, которая отправляет изменённые данные бота (update.jsp):
Мы также получаем данные бота и вставляем их в поля, меняем их и отправляем изменённые данные в POST-запросе. Отметим, что POST-запрос инициируется через отправку формы
где method=«post» означает, что данные формы попадут в POST, а action=«bot?action=submit» означает, что после отправки формы произойдёт переход по адресу bot?action=submit
Разберём для наглядности одно поле формы:
По нажатию кнопки Save все введённые данные будут отправлены в метод doPost() нашего сервлета. В данной строчке, мы задаём новый id.
Имя атрибута формы: «id» (name=«id»), значение, которое мы передадим — поле id объекта bot ($
), также, мы вносим в поле имеющееся значение, полученное в атрибуте «bot» (placeholder=»$ ).
Поскольку задачей этой статьи является описание работы POST- и GET-запросов, я объясняю смысл кода строк вскользь. Более подробно атрибуты страниц можно изучить в Справочнике по HTML.
Ну и давайте добавим самую примитивную страницу index.html, содержащую единственную ссылку на страницу bot:
Мы закончили с jsp / html и можем перейти, наконец, к моему любимому Java-коду.
Сервлет содержит 3 метода: init(), doGet() и doPost().
init() — вызывается при первой инициализации сервлета и единожды исполняет написанный в нём код. В нашем случае, создаётся экземпляр класса Bot.
doGet() — обрабатывает запрос GET.
doPost() — обрабатывает запрос POST.
Теперь мы по цепочке пройдём логику выполнения приложения и разберём, что как работает.
Итак, загружаем проект в Tomcat. Перед нами — одинокая ссылка «Bot». Нажимаем её.
Мы переходим в сервлет BotServlet. Метод doGet() исполняется всегда (ведь адресная строка есть всегда), метод doPost() исполняется только по запросу (у нас он есть —
Как отправлять HTTP-запросы на Java
Вступление
Протокол передачи гипертекста (HTTP)-это протокол прикладного уровня, который, без преувеличения, в значительной степени является основой просмотра Интернета в том виде, в каком мы его знаем.
Он используется для передачи документов гипермедиа между клиентом и сервером и является неотъемлемой частью каждого отдельного веб-приложения, включая любые API, использующие архитектуру REST.
Это позволяет браузеру взаимодействовать с сервером, отправляя запросы на определенные документы, будь то HTML-документы (возвращаемые в виде страниц, которые мы видим) или гипермедиа (изображения, видео и т.д.), Которые отображаются на страницах.
Как Работает HTTP?
Когда мы решаем посетить веб-сайт, за кулисами происходит то, что наш компьютер генерирует и отправляет запрос на сервер, на котором размещен веб-сайт.
HTTP-запрос может выглядеть примерно так:
Сервер должен ответить примерно так:
За этим следует ответный орган :
Затем тело ответа будет отображено в нашем браузере, и нас встретит страница!
полный список кодов состояния HTTP довольно длинный, хотя неплохо бы его просмотреть.
Отправка запросов с помощью HttpURLConnection
HttpURLConnection – это базовый класс Java для обработки HTTP-запросов и ответов.
Использование HttpURLConnection идеально подходит для простых HTTP-запросов, хотя, если вы хотите проще добавлять такие вещи, как заголовки или аутентификацию, вам будет проще полагаться на другие библиотеки, такие как Apache Commons. ССЫЛКА НА СТАТЬЮ APACHE ЗДЕСЬ
Самый простой способ создать экземпляр объекта HttpURLConnection – это использовать объект URL :
Типы запросов
Теперь, когда наш Экземпляр HttpURLConnection существует, мы можем определить для него тип HTTP-запроса:
Параметры запроса
Чтобы достичь этого, мы обычно придумываем способ сопоставить эти значения. Иногда люди определяют свои собственные классы для хранения этих значений с помощью простого Хэш-карты все будет в порядке:
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
Теперь, когда мы сопоставили наши параметры, нам нужно сделать пару вещей, чтобы подготовить их к нашему запросу:
Давайте реализуем пункты из списка:
И, таким образом, наш параметр готов к использованию в запросе.
Заголовки запросов
Если вы хотите добавить заголовок к запросу, это так же просто, как:
И если вы хотите прочитать заголовок запроса:
Тайм-ауты
Интервалы, как обычно, определяются в миллисекундах.
Так, например, время ожидания соединения истекает, если оно не может быть установлено в течение 10 секунд. Аналогично, это также приведет к тайм-ауту, если данные не могут быть считаны из соединения в течение 10 секунд.
ОТПРАВИТЬ запрос
С вашим запросом все готово, мы можем продолжить и отправить СООБЩЕНИЕ запрос:
Здесь мы отправляем postDataBytes в наш POST запрос, который представляет собой массив байтов. Ознакомьтесь с демонстрацией ниже для получения более подробной информации о том, как это создать.
ПОЛУЧИТЬ запрос
Запросы GET предназначены только для извлечения данных, поэтому давайте продолжим и получим ответ:
На этом этапе мы можем извлечь множество различных видов информации из соединения :
Демонстрация
Запуск этого фрагмента кода, безусловно, достаточно, чтобы получить исходный код страницы, которую мы указали для получения:
Вывод
Протокол передачи гипертекста (HTTP)-это протокол прикладного уровня, который, без преувеличения, является очень большим и важным компонентом для интернет-приложений.
HttpURLConnection – это базовый класс Java для обработки HTTP-запросов и ответов.
Использование HttpURLConnection идеально подходит для простых HTTP-запросов, хотя, если вы хотите создавать более сложные HTTP-запросы с заголовками или аутентификацией, у вас будет гораздо более простой опыт работы с такими библиотеками, как Apache Commons. ССЫЛКА НА СТАТЬЮ APACHE ЗДЕСЬ
Старые песни о главном. Java и исходящие запросы
(Иллюстрация)
Одна из задач, с которой сталкиваются 99,9% разработчиков, — это обращение к сторонним endpoint’ам. Это могут быть как внешние API, так и «свои» микросервисы. Сейчас все и вся бьют на микросервисы, да. Получить или отправить данные просто, но иногда изобретают велосипеды. Можете назвать 5 способов реализации запросов на Java (c использованием библиотек и без)? Нет — добро пожаловать под кат. Да? Заходите и сравните 😉
0. Intro
Задача, которую мы будем решать, предельно проста: нам необходимо отправить запрос GET/POST и получить ответ, который приходит в формате JSON. Чтобы не писать очередной оригинальный микросервис, я воспользуюсь примером, который предоставляет набор endpoint’ов с некоторыми данными. Все примеры кода максимально упрощены, никаких хитросделанных кейсов с auth-токенами и заголовками тут не будет. Только POST и GET, GET и POST, и так 5 раз или около того.
Итак, поехали.
1. Built-in Java solution
Было бы странно, если бы поставленную задачу нельзя было решить без использования сторонних библиотек. Конечно, можно! Но грустно. Пакет java.net, а именно HttpURLConnection, URL и URLEnconder.
Для отправки запроса, что GET, что POST, необходимо создать объект URL и открыть на его основе соединение:
Далее необходимо сдобрить соединение всеми параметрами:
И получить InputStream, откуда уже прочитать все полученные данные.
И, собственно, вот такой ответ мы получим (он будет одинаков для всех последующих примеров, ибо мы работаем с одними и теми же endpoint’ами):
В случае с POST-запросом все немного сложнее. Мы же хотим не только получить ответ, но и передать данные. Для этого нам нужно их туда положить. Документация нам говорит что это может сработать следующим образом:
Где getParamsString это простой метод, перегоняющий Map в String, содержащие пары «ключ-значение»:
При успешном создании мы получим объект обратно:
Ссылочка на source, который можно запустить.
2. Apache HttpClient
Если уйти в сторону от встроенных решений, то первое, на что мы наткнемся — HttpClient от Apache. Для доступа нам понадобится сам JAR-файл. Или, так как я использую Maven, то соответствующая зависимость:
И то, как выглядят запросы с использованием HttpClient’a, уже намного лучше (source):
Мы получили те же данные, но написали при этом вдвое меньше кода. Интересно, куда еще могут завести поиски в таком, казалось бы, базовом вопросе? Но у Apache есть еще один модуль, решающий нашу задачу.
3. Apache Fluent API
И уже с использованием Fluent Api наши вызовы становятся намного читабельнее (source):
И как бонус — пример. Если мы хотим передавать данные в боди не как форму, а как всеми любимый JSON:
По сути вызовы схлопнулись в одну строчку кода. Как по мне, это намного более дружелюбно по отношению к разработчикам, чем самый первый способ.
4. Spring RestTemplate
Что же дальше? Дальше опыт меня завел в мир Spring. И, что не удивительно, у спринга тоже имеются инструменты для решения нашей простенькой задачи (странно, правда? Задача, даже не так — потребность! — базового уровня, а решений зачем-то больше одного). И первое же решение (базовое), которое вы найдете в экосистеме Spring, это RestTemplate. И для этого нам нужно тянуть уже немалую часть всего зоопарка. Так что если вам нужно отправить запрос в НЕспринговом приложении, то ради этого лучше не тянуть всю кухню. А если спринг уже есть, то почему бы и да? Как притянуть все, что необходимо для этого, можно посмотреть здесь. Ну а собственно GET-запрос с использованием RestTemplate выглядит следующим образом:
Гуд. НО! Работать со строкой уже не хочется, тем более есть возможность получать не строки, а готовые объекты, которые мы ожидаем получить! Создаем объект Post:
Здесь:
Builder, Getter, Setter — сахар от Lombok, чтобы не писать все руками. Да, вот она, лень-матушка.
JsonIgnoreProperties — чтобы в случае получения неизвестных полей не вылетать в ошибку, а использовать те поля, которые нам известны.
Ну и toString, чтобы выводить наши объекты в консоль, и это можно было прочитать. Ну и собственно наши GET- и POST- запросы перевоплощаются в (source):
И у нас уже в руках объекты, а не строка, которую надо разбирать самостоятельно.
Кул. Теперь мы можем написать некоторую обертку вокруг RestTemplate, чтобы запрос строился корректно. Выглядит не так уж плохо, но, как по мне, это можно еще улучшить. Чем меньше кода пишется, тем меньше вероятность ошибки. Все же знают, что основная проблема зачастую PEBCAK (Problem Exists between Chair and Keyboard)…
5. Spring Feign
И тут на сцену выходит Feign, который входит в состав Spring Cloud. Сначала добавим к уже добавленному ранее спринговому окружению Feign-зависимость:
По сути все, что надо, это объявить интерфейс и сдобрить его хорошей жменькой аннотаций. Особенно данный подход будет симпатичен тем, кто пишет контроллеры с использованием спринга.
Вот что нам надо сделать для отправки запросов посредством Feign (source).
Красота, не правда ли? И да, те модели данных, которые мы писали для RestTemplate, отлично переиспользуются здесь.
6. Conclusion
Отправка GET запросов в Java
Сегодня мы рассмотрим, как отправлять GET запросы в Java. Для отправки http запросов мы будем использовать библиотеку Apache HttpClient.
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class HttpClientGetRequest <
public static void main(String[] args) throws IOException <
CloseableHttpClient httpClient = HttpClients.createDefault();
// создаем объект клиента
HttpGet request = new HttpGet(«https://myrusakov.ru»);
// добавляем заголовки запроса
request.addHeader(«Author», «MyRusakov.Ru»);
request.addHeader(HttpHeaders.USER_AGENT, «MyRusakov.HttpClient»);
CloseableHttpResponse response = httpClient.execute(request);
// получаем статус ответа
System.out.println(response.getProtocolVersion()); // HTTP/1.1
System.out.println(response.getStatusLine().getStatusCode()); // 200
System.out.println(response.getStatusLine().getReasonPhrase()); // OK
System.out.println(response.getStatusLine().toString()); // HTTP/1.1 200 OK
> finally <
// закрываем соединения
response.close();
>
> finally <
httpClient.close();
>
Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!
Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
Комментарии ( 0 ):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.
Copyright © 2010-2021 Русаков Михаил Юрьевич. Все права защищены.
Как передать массив как параметр строки GET-запроса в Java (Spring)?
Из-за наличия списка List внутри фильтра, возникают проблемы с получением его в контроллере.
Тщательно изучив мануал и вопрос на тему передачи объектов в строке GET-запроса, мне так и не удалось добиться успеха. По-прежнему неясно, в каком виде надо передать массив с клиента, и что сделать на сервере, чтобы он его увидел как список (происходят разного вида ошибки при маппинге фильтра). Использую такую стратегию (для получения всего, кроме списка):
1 ответ 1
Решение вашей задачи для контроллера:
Чтобы это решение заработало, запрос нужно полностью приводить в url encoded вид. Например, запрос для объекта вида
Будет выглядеть так:
http(s)://
Подробнее про url encoding можно прочесть хотя бы на вики
И немного бубнежа от меня:
Может быть вам вместо объекта использовать набор параметров для фильтрации? Параметров limit и direction, как правило, достаточно для большинства задач
В контроллере не должно быть никакой логики (даже если вы в качестве примера привели инициализацию ObjectMapper и маппинг строки в объект)
Выносите в конфигурацию всего приложения инициализацию ObjectMapper, делайте метод его создания бином и затем инжекьте его во все сервисы.
Не забудьте где-нибудь прописать ExceptionHandler для ошибок маппинга.