Работа с HTTP-запросами в Java-cервлетах: GET и POST

Для начала рассмотрим GET-запрос.

GET-запросы позволяют клиенту передавать параметры через адресную строку браузера. Эти параметры затем можно легко извлечь из объекта HttpServletRequest в сервлете.

Представьте, что клиент вводит в адресной строке следующее:

localhost:8080\helloservlet\getpostservlet\?param1=Hello&param2=World

Здесь param1 имеет значение “Hello”, а param2“World”.

С помощью различных методов эти параметры можно перехватывать, например, с помощью метода getParameter получим значения параметров и запишем в строки.    

Пример программы:

import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.annotation.*; @WebServlet(“/getpostservlet”) public class MyServlet extends HttpServlet{ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //С помощью различных методов эти параметры //можно перехватывать например с помощью //метода getParameter получим значения //параметров и запишем в строки. String par1 = req.getParameter(“param1”); String par2 = req.getParameter(“param2”); PrintWriter pw = resp.getWriter(); //На странице клиента выведутся //значения параметров. pw.println(par1); pw.println(par2); //Также есть другие методы для удобства работы //с параметрами например getParameterValues, //getParameterNames …. //Также мы можем получить некоторую информацию //о запросе клиента с помощью методов ниже. //например полный URL. pw.println(req.getRequestURL()); //или получим IP хоста pw.println(req.getRemoteHost()); } }

Скомпилируем файл и в адресной строке передадим параметры сервлету по адресу /getpostservlet. Он должен отправить их обратно клиенту в браузер.

Как видим, сервлет успешно вернул клиенту параметры. Также сервлет отправил клиенту адрес и ip хоста, как видим.


Get запрос с помощью формы

Пусть сервлет отправляет форму с двумя полями и кнопкой отправки пользователю в браузер.

Если он в нее что-то введет то данные отправятся в наш сервлет по методу GET (в форме ниже можно увидеть method=’get’).

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

localhost:8080\helloservlet\getpostservlet\?param1=(то, что ввел в текстовое поле пользователь)&param2=(то, что ввел в текстовое поле пользователь)  

Пример программы:

import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.annotation.*; @WebServlet(“/getpostservlet”) public class MyServlet extends HttpServlet{ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String par1 = req.getParameter(“param1”); String par2 = req.getParameter(“param2”); PrintWriter pw = resp.getWriter(); //Отправляем клиенту, который обращается //к этому сервлету форму чтобы он мог ввести //туда параметры в адресной строке. pw.println(“” + “” + “” + “
” + “” + “” + “” + “
” + “” + ““); //Отправим присланные параметры обратно клиенту pw.println(par1); pw.println(par2); } }

Скомпилируем файл сервлета, перейдем по адресу /getpostservlet. Как видим, сервлет отправил клиенту форму и он теперь может вводить в поля параметры param1 и param2.

Когда пользователь нажимает кнопку, введенные им значения параметров param1 и param2 отправляются в сервлет.

Как видим, в адресной строке URL идентичен тому, что мы вводили руками в предидущем примере, только здесь мы использовали форму для отправки параметров.

Также видим Hello World. То есть сервлет вернул клиенту параметры, которые клиент отправил в сервлет через форму.


Post запрос с помощью формы

Но часто на безопасно передавать параметры методом get, так как, как мы видели, они выводятся в адресной строке.

Чтобы они не выводились в адресной строке следует передавать параметры из формы методом POST.

Пример программы:

import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.annotation.*; @WebServlet(“/getpostservlet”) public class MyServlet extends HttpServlet { // Когда пользователь обращается к сервлету по адресу // http://localhost:8080/helloservlet/getpostservlet // он совершает GET-запрос. Поэтому отправлять форму // клиенту будем в doGet. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter pw = resp.getWriter(); // Отправляем клиенту, который обращается // к этому сервлету, форму, чтобы он мог ввести // нужные параметры в адресной строке. // Но в этот раз эта форма отправляет POST-запрос. pw.println(“” + “” + “” + “
” + “” + “” + “” + “
” + “” + ““); } // А форма, как можно увидеть выше, отправляет POST-запрос, // поэтому принимать параметры и отправлять их обратно // клиенту будем в doPost. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String par1 = req.getParameter(“param1”); String par2 = req.getParameter(“param2”); PrintWriter pw = resp.getWriter(); // На странице клиента выведутся значения // параметров, при этом у клиента в адресной // строке ничего не будет. pw.println(par1); pw.println(par2); } }

Скомпилируем файл сервлета, перейдем по адресу /getpostservlet. Как видим, сервлет отправил клиенту форму и он теперь может вводить в поля параметры param1 и param2.

Когда пользователь нажимает кнопку, введенные им значения параметров param1 и param2 отправляются в сервлет.

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

Также видим самое главное, что параметров в адресной строке нет, они скрыты благодаря методу Post.

Использование аннотации @WebServlet

Чтобы не конфигурировать путь, по которому будет происходить обращение к сервлету в web.xml можно использовать аннотацию WebServlet в коде сервлета.

import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; // Вместо xml кода путь, по которому будем обращаться к сервлету, // в строке браузера можно указать в этой аннотации. @WebServlet(“/myservlet”) public class MyServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter pw = resp.getWriter(); pw.write(“Hello World!!!”); } }

Тогда весь тот код, что был написан в файлике web.xml можно будет убрать. Также важно в metadata-compile установить false вместо true

Компилируем файл сервлета и обращаемся по пути:

Методы Java-cервлета

Помимо doGet у сервлета есть и другие методы.

Рассмотрим вкратце зачем нужны методы init, doPost, service и destroy.

import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyServlet extends HttpServlet { /* public void init() throws ServletException { // При создании объекта сервлета, который создается один раз // за все время работы сервера вызывается метод init(), в // котором можно инициализировать какие-то данные до того // как сервлет начнет их обрабатывать. } */ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Этот метод для приема Get запросов. // Получаем поток PrintWriter с которым мы уже знакомы из resp // через который будем отправлять данные клиенту. PrintWriter pw = resp.getWriter(); pw.write(“Hello World!!!”); } /* protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Этот метод для приема POST запросов. // Ниже пример того как мы можем вызывать // и GET запрос при POST запросе вызывая верхний метод // и передав ему параметры из этого метода doPost. doGet(req, resp); } public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException { // Каждый раз когда пользователь отправляет что-либо из браузера // вызывается метод service(), который определяет вид запроса, // который передал пользователь (GET, POST, PUT, DELETE) // и вызывает соответствующий метод (doGet, doPost, // doPut, doDestroy) метод service автоматически вызывает // методы doGet, doPost…, поэтому нет необходимости переопределять // его нет кроме редких случаев когда нам нужно чтобы все // возможные запросы обрабатывались в одном методе // гость в методе service так как этот метод // перехватывает все возможные запросы. } public void destroy() throws ServletException { // при удалении объекта сервлета можно очистить какие-то ресурсы. // например закрыть подключение к базе } */ }

Создание первого Java-сервлета

Ниже приведен пример сервлета.

Класс сервлета наследуется от класса HttpServlet и в нем реализуются методы doGet, doPost.

В этих методах происходит прием информации от клиента через HttpServletRequest req и отправка информации клиенту через HttpServletResponse resp.

Пример программы:

import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyServlet extends HttpServlet { //Этот метод для приема Get запросов. //Что такое Get, Post запросы разберемся позже. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //Получаем поток PrintWriter с которым мы уже знакомы //из resp через который будем отправлять данные клиенту. PrintWriter pw = resp.getWriter(); pw.write(“Hello World!!!”); } }

Чтобы запустить сервлет его нужно сначала скомпилировать используя библиотеку в папке lib servlet-api.jar.

Перейдем в консоли в папку apache-tomcat-9.0.80\webapps\helloservlet\WEB-INF\classes и здесь скомпилируем MyServlet.java с использованием servlet-api.jar:

В папке как обычно появиться файлик с байткодом .class.


Конфигурация Сервлета с помощью web.xml

В файле Web.xml настраивается то, как будет развернут наш сервлет MyServlet.java.

Например, по какому адресу клиенты будут отправлять запросы для обработки нашим сервлетом и многие другие настройки.

Web.xml:

MyServlet /myservlet MyServlet MyServlet 5

Теперь можно проверять работу нашего сервлета.


Проверка работы сервлета

Запускаем файл startup.bat в папке bin для запуска контейнера сервлетов, то есть сервера.

Ждем пока полностью запуститься наш Tomcat.

Теперь через браузер сделаем запрос к нашему сервлету по аддресу, который мы прописывали в web.xml.

Всё работает. Как видим, мы как клиент через браузер отправили запрос серверу по адресу http://localhost:8080/helloservlet/myservlet и он отправил в ответ Hello World!!!.

Java Enterprise Edition (EE)

Java EEстандарт разработки веб-приложений используя язык Java.

Предоставляет множество средств для реализации клиент-серверных приложений.

В Java EE входят разные технологииServlets, JSP, JSTL и т.д.

В данном разделе будем рассматривать Сервлеты.


Что такое Сервлет?

Для начала нужно узнать что такое клиент-серверное приложение.

Example

Говоря просто, механизм его работы такой:

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

Сервлет – это и есть этот код, который обрабатывает эти запросы.


Контейнер сервлета

Сервер (также называют серверная программа или контейнер сервлета) – это то, что содержит в себе сервлет.

Сервер работает без остановки, чтобы постоянно принимать запросы и давать ответ.

Контейнер сервлета обеспечивает функционирование сервлета (управление его жизненным циклом).

Example

Жизненный цикл сервлета таков:

При запуске контейнера сервлета он загружает в себя сервлет, создает его объект и вызывает у него метод init(), и теперь сервлет готов к обработке запросов

Далее контейнер сервлета будет передавать запросы пользователей в метод service сервлета. Каждый запрос пользователя обрабатывается в отдельном потоке.

При завершении работы контейнера сервлета останавливается и сервлет, путем вызова на нем метода destroy.

Есть много контейнеров сервлетов, например, Tomcat (далее будем пользоваться им).

Tomcat скачать в интернете довольно просто. Переходим по ссылке и скачиваем:

https://tomcat.apache.org/download-90.cgi

Далее контейнер сервлета будем называть сервером.


Структура сервера и веб-приложения

Заглянем внутрь скачанной по ссылке папки.

Веб-приложения, в которых хранятся сервлеты, хранятся в папке webapps на сервере Tomcat.

Создадим веб-приложение с именем helloservlet, и в нем будут храниться сервлеты.

Файловая структура веб-приложения всегда такая:

\WEB-INF\classes – здесь хранятся сервлеты.

Как видим, мы создали здесь сервлет с именем MyServlet.java.

WEB-INF\web.xml – в этом файле совершаются настройки сервлетов.