Java

Java SE

 веб-технологии и Enterprise-разработка

Maven, Git, Junit, Tomcat, Servlet;

Glassfish

Spring MVC, Core, Security, JPA, Hibernate, REST.

Java Core

more...

JAVA EE: Разработка web-приложения. View и Controller

Четвертая статья серии. В ней мы используя наш каркас приложения который мы создали на втором уроке продолжим изучение технологии Java EE. Познакомимся с дескриптором развертывания web.xml, уменьшим количество повторяемого кода в jsp страницах путем использования jsp сегментов. Далее мы создадим наш первый сервлет, который будет играть роль контроллера, и обработаем наш первый запрос с клиента.

1Готовый снимок урока можно забрать здесь https://github.com/TalismanFR/MyBlog/tree/article_4

1Повторю еще раз, что для работы нам понадобится каркас приложения созданный на втором уроке.

 Перемещение JSP страниц в WEB-INF

Сейчас в нашем проекте имеется три jsp страницы: index.jsparticle.jspregistration.jsp. Сейчас доступ к каждой странице можно получить просто набрав путь к ней: localhost:8080/myblog/article.jsp. Что-бы исправить этот недостаток необходимо переложить все jsp файлы внутрь папки WEB-INF. Доступ к этой папке из браузера невозможен, вызов localhost:8080/WEB-INF/… приведет лишь к ошибке 404.

Папка WEB-INF была создана намерено что-бы разграничить файлы классов и библиотеки классов используемые приложением от остальных html, jpg и прочих файлов, к которых пользователь должен иметь прямой доступ по протоколу http.

Создадим в папке WEB-INF новую папку «views«.

Создание новой папки

 Во вновь созданную папку необходимо переместить файлы article.jsp и registration.jsp. Файл index.jsp перемещать не нужно. Он входной файл приложения. В результате проделанных действий, менеджер проектов должен выглядеть следующим образом:

Менеджер проектов

Теперь прямой доступ к перемещенным файлам невозможен. Что-бы перенаправить вывод на эти файлы необходимо использовать сервлет. Им мы займемся чуть позже. А пока познакомимся с дескриптором развертывания.

Создание дескриптора развертывания и jsp сегментов

Пришло время создать дескриптор развертывания приложения.

Дескриптор развертывания — это файл xml файл, который описывает настройки развертывания компонента на сервере. JavaEE приложение и каждый его модуль содержит свой собственный дескриптор.  Поскольку информация в дескрипторе объявляется декларативно, она может быть изменена без вмешательства в исходный код. Сервер JavaEE действует согласно считанному дескриптору развертывания.

Нажмите на кнопку «Создать файл…»  и в категории «Веб» выберите тип файла «Стандартный дескриптер развертывания«.

Создание дескриптора развертывания

После нажмите кнопку «Готово«.

В папке WEB-INF создался новый файл web.xml.

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

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/
       javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
     version="3.0">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>

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

 Создайте новую папку с именем jspf в папке WEB-INF. Теперь создайте новый jsp сегмент. В окне выбора типа файла выберите «jsp«, далее введите название файла header и поставьте галочку в поле «Создать в виде сегмента jsp«.

Тем-же способом создайте файл footer.jspf.

В файл header.jspf необходимо скопировать код из jsp страниц вплоть до тега </header>.

<%@ page pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="css/style.css">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Мой блог</title>
    </head>
    <body>
        <header>
            <a href="/"><img alt="Логотип" id="top-image" src="#"/></a>
            <div id="user-panel">
                <a href="#"><img alt="Иконка юзера" scr=""/></a>
                <a href="javascript:void(0);">[Панель для юзера]</a>
            </div>
        </header>

Во всех jsp файлов этот кусок кудок необходимо удалить.

В файл footer.jspf переносим код от тега <footer>

<%@ page pageEncoding="UTF-8" %>
<footer>
            <div>
                <span>Тестовое приложение JAVA EE</span>
                <span><a target="_blanc" href="http://onedeveloper.ru/search?w=Java">Уроки по JavaEE</a></span>
            </div>
        </footer>
    </body>
</html>

и так же удалить этот кусок кода из всех jsp страниц.

Отлично, мы создали jsp сегменты для нашего сайта. Теперь необходимо указать в какие страницы нужно вставлять верхний и нижний колонтитулы. Это можно сделать путем вствки тега <jsp:include> в jsp файлы. Однако это не решает проблему повторяемости кода. Для этой задачи можно использовать дескриптор развертывания.

Откройте файл дескриптора развертывания web.xml и перейдите на вкладку «Страницы«. В ней добавте новую группу свойств. В шаблоне адресов нужно указать файлы к которым будет применяться правила, в нашем случае это index.jsparticle.jsp и registration.jsp. Поэтому поле шаблонов адресов укажите:

/WEB-INF/views/*, /index.jsp

так же можете добавить описание правил.

Создание группы правил jsp

Далее выберите файлы для вводной и заключительной части (header.jspf и footer.jspf соответственно). В итоге, вкладка «Страницы» должна выглядеть следующим образом:

Вкладка "Страницы"

 Сохранив и запустив проект вы увидите что разметка осталась прежней, значит мы все сделали правильно.

Создание servlet’a

Сервлет — java интерфейс необходимый для расширения функционала веб-сервера. Именно сервлеты принимают и обрабатывают запросы поступившие от пользователя, на основе их решает как поступить дальше и какой ответ дать пользователю. Для разных запросов пользователя можно назначить свой сервлет.

Будем рассматривать сервлеты версии 3.0 (самая последняя на момент написания статьи), в ней активно используется понятие аннотация, благодаря чему работа с сервлетами становится весьма проста.

1К одному и тому же запросу пользователя можно привязать не более одного сервлета.

Как мы говорили ранее, сервлет у нас будет играть роль контроллера. Он будет принимать запросы пользователей, на их основе выбирать тот или иной бизнес-метод, вызывать необходимый view и передавать нужные параметры.

Что-бы создать контроллер нажмите на кнопку создания нового файла , и списке типа файла выберите «Сервлет». Введите имя сервлета «web_controller» и имя пакета «Controller«.

Окно создания сервлета

Нажмите «Готово«.

Среда разработки создала готовый каркас сервлета. В нем объявлены методы doGet и doPost которые обрабатывают GET и POST запросы с клиента соответственно. Эти методы получают два параметра:

HttpServletRequest request;
HttpServletResponse response;

Request содержит информацию полученную от пользователя, Response содержит информацию которая будет передана пользователю.

IDE объединила оба метода в один — processRequest и ему передаются оба параметра. Если важно различать методы doGet и doPost, то реализацию их обработчика нужно писать прямо в них. Нам вполне сойдет и processRequest.

Что-бы зарегистрировать сервлет на сервере используется аннотация вида @WebServlet. В данный момент в ней указана имя сервлета и адреса вызовов которые будет обрабатывать сервлет. Давайте поправим поле urlPatterns так, что-бы оно указывало необходимые нам пути. Замените строку объявления сервлета на следующею:

@WebServlet(name = "web_controller", urlPatterns = {"/article", "/registration"})

Теперь каждый запрос пользователя произведенный по адресу ../article или ../registration будет обрабатывать данный сервлет.

Обработаем данные запросы в сервлете. Будем вызывать соответствующие представления в ответ на данные запросы пользователей.

Добавьте в тело функции processRequest следующею строку:

String userPath=request.getServletPath();

Метод getServletPath() возвращает путь по которому обратился пользователь.

 Далее впишите:

  if ("/article".equals(userPath)){
            // TODO: обработка запроса статьи
  }else
  if ("/registration".equals(userPath)){
            //TODO: обработка запроса регистрации
  }

 Это заготовка для обработчика. В заключение добавьте следующий строку:

 request.getRequestDispatcher("/WEB-INF/views"+userPath+".jsp").forward(request, response);

Методом getRequestDispather вызываем необходимое нам представление (jsp страницу) и передаем ей параметры запроса и ответа.

Теперь набрав в строке адреса браузера http://localhost:8080/myblog/article мы попадем на страницу статьи, а набрав http://localhost:8080/myblog/registration на страницу регистрации. Тем самым мы наглядно убедились что наш сервлет обработал эти два запроса и перенаправил нас на нужные страницы.

Полный код контроллера приведен ниже:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controller;

import com.sun.org.apache.bcel.internal.generic.GOTO;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author Egorov A.
 */
@WebServlet(name = "web_controller", urlPatterns = {"/article", "/registration"})
public class web_controller extends HttpServlet {


    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        String userPath=request.getServletPath();
        if ("/article".equals(userPath)){
            // TODO: обработка запроса статьи
        }else
        if ("/registration".equals(userPath)){
            //TODO: обработка запроса регистрации
        }
        
        request.getRequestDispatcher("/WEB-INF/views"+userPath+".jsp").forward(request, response);
    }

    /**
     * Handles the HTTP
     * <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP
     * <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}

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

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

1Готовый снимок урока можно забрать здесь https://github.com/TalismanFR/MyBlog/tree/article_4

Следующая статья будет посвещена работе приложения с базой данных. Для начал мы ее создадим, затем использую панель управления сервером (с ней мы тоже познакомимся) настроим пуллы соединений.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *