Що таке сервлет
Спочатку розберемося, що таке сервлет і чому ти так часто чуєш про нього. Java Servlet API - стандартизований API, призначений для реалізації на сервері та роботі з клієнтом за схемою запит-відповідь. Сервлет – це клас, який вміє отримувати запити від клієнта та повертати йому відповіді. Так, сервлети Java — саме ті елементи, за допомогою яких будується клієнт-серверна архітектура. Якщо пам'ятаєш, про неї ми вже говорабо в одній із статей циклу. Не будемо ходити навкруги: давай відразу напишемо трохи коду.Що потрібно для створення веб-програми
Для комфортної роботи з сервлетами Java тобі знадобиться Intellij IDEA Ultimate Edition. Вона платна, але можна активувати 30 днів пробного періоду або ж скористатися early access версією — вона завжди безкоштовна. Також установи сервер нашої програми - Apache Tomcat. Tomcat – це контейнер сервлетів: саме він обробляє вхідні запити ззовні та передає їх нашому додатку. Завантажити Tomcat можна за цим посиланням .Створюємо перший веб-додаток
Якщо все готово, створимо Maven-проект. Якщо ти не знайомий з Мавеном, зверни увагу на попередню статтю . Ну що почнемо!-
У pom.xml додамо залежність javax.servlet-api та встановимо packaging war:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>servlets</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> </dependencies> </project>
Клас простого сервлету:
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/hello") public class MainServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); PrintWriter printWriter = resp.getWriter(); printWriter.write("Hello!"); printWriter.close(); } }
-
Для запуску програми потрібно створити конфігурацію Tomcat:
-
Далі вказуємо, яку версію Tomcat ми будемо використовувати, URL, яким можна звертатися до сервера і порт. У тебе має вийти приблизно так:
-
Залишилося вказати артефакт (зібраний проект у jar-архів), який розгорнеться у контейнері. Можна натиснути кнопку Fix і вибрати war exploded : це означає, що після перескладання проекту артефакт автоматично поміщатиметься в контейнер сервлетів.
-
Application context за промовчанням встановлений servlets_war_exploded , а це означає, що до додатку потрібно звертатися за адресаою: http://localhost:8080/servlets_war_exploded .
Навіщо нам зайвий текст? Видалимо непотрібне. Тепер адресаа програми у нас така: http://localhost:8080 .
-
Натискаємо ОК. Бачимо, що у нас з'явилася можливість запуску програми:
Тепер при запуску програми повинен відкритися браузер і видати 404 помилку. Це логічно, адже за адресаою http://localhost:8080/ повинен бути сервлет з мапінгом “/”, а у нашого єдиного сервлету мапінг "/hello" .
-
Звертаємось до нього за адресаою http://localhost:8080/hello , і отримуємо очікувану відповідь - рядок "Hello"!
Робота з параметрами та сесією
Удосконалимо наш сервлет, щоб він міг обробляти параметри запиту та працювати з сесією:import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/hello")
public class MainServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
Integer visitCounter = (Integer) session.getAttribute("visitCounter");
if (visitCounter == null) {
visitCounter = 1;
} else {
visitCounter++;
}
session.setAttribute("visitCounter", visitCounter);
String username = req.getParameter("username");
resp.setContentType("text/html");
PrintWriter printWriter = resp.getWriter();
if (username == null) {
printWriter.write("Hello, Anonymous" + "<br>");
} else {
printWriter.write("Hello, " + username + "<br>");
}
printWriter.write("Page was visited " + visitCounter + " times.");
printWriter.close();
}
}
Зараз сервлет працює з сесією, збільшуючи лічильник visitCounter при кожному відвідуванні сторінки. Якщо атрибут visitCounter ще не створений (при першому відвідуванні сторінки), метод getAttribute() поверне null, тому необхідно проводити перевірку на null. Те саме стосується параметрів запиту. Якщо користувач не передав параметр username, його значення буде null. У такому разі вітаємо користувача як анонімного. Щоб передати параметр GET-запиту, використовуються path-variables, тобто потрібно звернутися за посиланням http://localhost:8080/hello?username=Pavel . Детальніше про http-запити можна почитати у попередній статтіциклу. Тепер наша програма має мінімальну логіку, але трохи дратує 404-а помилка в root-шляху. Щоб виправити її, створимо ще один сервлет і замапи його на початкову сторінку @WebServlet("/"). Завдання цього сервлета – перенаправляти запити на шлях “/hello”. Зробити це можна двома способами: за допомогою forward чи redirect. Мабуть варто розібратися, в чому між ними різниця. forward - делегує обробку запиту іншому сервлет на сервері, клієнт при цьому не задіюється. Для цього до методу doGet() нового сервлета потрібно додати такий код:
getServletContext().getRequestDispatcher("/hello").forward(req, resp);
У цьому коді ми звертаємося до контексту сервлетів, з нього дістаємо диспетчер запитів потрібного сервлету та просимо його опрацювати конкретний запит із зазначеними параметрами (req, resp). redirect — повертає клієнту адресау, яким потрібно звернутися для обробки його запиту. Більшість браузерів переходять на передане посилання автоматично. Для реалізації редиректу потрібно додати цей код:
resp.sendRedirect(req.getContextPath() + "/hello");
Ми в HttpServletResponse викликаємо метод redirect() і передаємо йому адресау, на яку клієнту потрібно звернутися. Важлива деталь: http-параметри потрібно додати в кінці повного шляху редиректу, що не дуже зручно. У нашій ситуації краще використовувати forward, а буває так, що краще - redirect. Якщо розумітимеш різницю в їхній роботі, не помабошся з вибором. Код нового сервлета виглядає так:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// getServletContext().getRequestDispatcher("/hello").forward(req, resp);
resp.sendRedirect(req.getContextPath() + "/hello");
}
}
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ