Проект Java Servlet + jsp. Часть 1. Hello World.

Начинаю новую серию статей, в которой буду рассказывать, как я делал для своего портфолио небольшой проект с помощью Java Servlet, Hibernate и jsp страниц.

Для начала потренируюсь на простейшем приложении, которое будет выводить Hello World и ничего больше. Буду пошагово описывать свои действия в этой статье. Под конец у нас будет приложение, которое кроме приветствия на странице будет выводить данные, полученные из сервлета.


Первым делом, нужно создать новый проект (очевидно). Я работаю в Intellij IDEA, и там в окне создания нового проекта выбираю Java Enterprise (или Jakarta EE в других версиях идеи).

В списке технологий выбираю Servlet.

Ну и в третьем окне выбираю название проекта. Так как это тренировочный проект, ничего умного я не ввожу — просто HelloWorld. В других версиях идеи выбор имени может быть на первом шаге.

И готово: идея сама создала несколько файлов, включая pom.xml с зависимостями, один сервлет, который просто выводит Hello World, и jsp страницу.

После этого я собрал проект и закинул его в tomcat. Запустил сервер и увидел приветствие:

Что происходит? По умолчанию попадаем на страницу index.jsp, на которой кроме заголовка есть ссылка на адрес hello-servlet. Согласно аннотации в классе HelloServlet.java, этот адрес соответствует этому сервлету. Поэтому, при нажатии на ссылку мы попадаем в сервлет, который в методе DoGet просто пишет то же самое приветствие в заголовке.

Что отсюда мы узнаём? Что к сервлету можно привязать адрес, и при переходе на него по ссылке автоматически вызывается метод DoGet.

Сделать привязку можно в аннотациях, как сделано автоматически в этом примере, или в файле web.xml. Таким образом, строчку перед заголовком класса можно заменить на текст в файле. Было:

@WebServlet(name = "helloServlet", value = "/hello-servlet")

Стало:

    <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.example.HelloWorld.HelloServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello-servlet</url-pattern>
    </servlet-mapping>

Здесь намного больше текста: нужно указать имя сервлета и адрес соответствующего класса и потом связать этот сервлет с адресом. Поэтому в своём проекте, я буду использовать только аннотации, но, например, у меня на работе в проекте используется второй метод с файлом web.xml.

Теперь предлагаю немного поменять сервлет, чтобы он не просто выводил html код на страницу, а отправлял нас к jsp странице, в которой уже будет прописан нужный код. Всё-таки это не функция бэка и сервлетов — построчно создавать html код.

Теперь сервлет выглядит следующим образом:

@WebServlet(name = "helloServlet", value = "/")
public class HelloServlet extends HttpServlet {
    private String message;
    
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        request.getRequestDispatcher("main.jsp").forward(request, response);
        response.flushBuffer();
    }

}

Я изменил адрес сервлета на /, чтобы он открывался сразу же по умолчанию. И создал страницу main.jsp (вместо index.jsp) в папке webapp, на которую мы хотим попасть. Страница всё ещё очень простая.

<html>
<head>
    <title>Hello World!</title>
</head>
<body>
    <h1>Hello World!</h1>
</body>
</html>

Напоследок предлагаю передать из сервлета на страницу какие-нибудь данные. Например, случайное число. Для этого используем метод request.setAttribute(), где задаём имя атрибута и потом его значение.

@WebServlet(name = "helloServlet", value = "/")
public class HelloServlet extends HttpServlet {
    private String message;

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        Random random = new Random();
        int randomNumber = random.nextInt();

        request.setAttribute("number", randomNumber);
        request.getRequestDispatcher("main.jsp").forward(request, response);
        response.flushBuffer();
    }

А в jsp-странице достать данные можно, указав имя атрибута в фигурных скобках после $.

<html>
<head>
    <title>Hello World!</title>
</head>
<body>
    <h1>Hello World!</h1>
    <h2>Random number: ${number}</h2>
</body>
</html>

Так как у нас примитив (просто число), то одного имени достаточно. Если бы у нас был сложный объект, то доступ к его полям происходил бы через точку (будто мы всё ещё в джаве и все поля у нас public). Например, ${object.field}. Элементы списка достаются по индексу в квадратных скобках (как в джаве делается с массивами): ${list[0]}. Эти знания очень пригодятся при работе с базой данных.


В этой статье я создал простейший проект с сервлетами, изменил адрес сервлета, создал новую jsp-страницу и передал ей данные с бэка. В следующих статьях я начну работу с базой данных, буду доставать данные оттуда, и даже записывать их обратно (метод doPost). Сервлетов будет немного больше, поэтому нужно будет между ними перемещаться.