Progress28.ru

IT Новости
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Разработка веб приложений на java

Java EE

Новые статьи и уроки JAVA

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

Третья статья по разработке web-приложения.

В данной статье мы спроектируем наше приложение, обговорим основные моменты, касающиеся его логики функционирования, а также приступим к работе со средой разработки (IDE).

Также мы рассмотрим способ подключение IDE к базе данных MySQL, создадим новую базу данных для нашего web-приложения.

Разрабатываемый нами сайт будет подобием мини-блога с возможностью чтения, добавления и редактирования статей. Также будет реализован функционал регистрации пользователей, комментирования статей и распределения прав доступа. Это первоначальный набор возможностей, который будет реализован, в дальнейшем будем вырабатывать новые требования к системе.

Структура сайта

Из приведенного выше описания можно составить структуру сайта:

  1. Главная страница сайта. Содержит список последних добавленных статей.
  2. Страница чтения статьи. Содержит полное содержание выбранной статьи.
  3. Страница регистрации.
  4. Зона администрирования. Ограниченный вход только для авторизованных пользователей, имеющих права администратора сайта.

Наглядно расписанную структуру можно увидеть на рисунке ниже:

Архитектура Java EE проекта

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

При работе с JSP можно уместить бизнес-логику внутри jsp страниц с использованием скриплетов , однако такой подход не рекомендуется даже для малых проектов. Причин, почему этот подход является плохим, можно найти множество на просторах интернета, в частности:

  1. Скриплеты не масштабируемы и трудно поддерживаемы.
  2. Смесь программирования, верстки и дизайна в одном флаконе: верстальщик явно не обрадуется, глядя на jsp страницу с кучей непонятного для него кода.
  3. Читать такие страницы крайне неудобно.
  4. Сложность тестирования.

И это список далеко неполный.

Из вышесказанного выведем еще одно важное правило:

1Не злоупотребляйте, а лучше старайтесь не использовать скриплеты внутри jsp страниц.

В данной серии статей мы будем следовать паттерну MVC. Паттерн достаточно известный и подробно вдаваться в его подробности не имеет смысла.

Опишем основные моменты.

  • Модель (M Model): Хранит в себе бизнес-логику приложения, регулирует доступ к данным и их изменение.
  • Вид (V View): View отображает содержимое модели, определят как необходимо представить данные, полученные от модели. View берет на себя сбор пользовательских данных и передачи их контроллеру.
  • Контроллер (C Controller): Контроллер определяет поведение всего приложения, получает от view пользовательские данные, интерпретирует их в действия, выполняемые с помощью модели. Контроллер передает view указание, какое представление необходимо применить, на основе результатов работы модели и взаимодействия с пользователем.

Применительно к Java EE технологии шаблон MVC реализуется следующим образом. Сервлет используется как контроллер для обработки входящих запросов пользователей от представления, которое реализуется с помощью страниц jsp. Модель же представляет собой EJB сессионные компоненты, а также классы сущности (JPA), которые в свою очередь содержат в себе данные из БД.

Создание web-проекта

Приступим к работе со средой разработки.

1. Запустите Ваше IDE. Автор использует NetBeans.

2. Кликните по иконке «Создать проект. » , в списке категорий выберите «Java Web», в появившемся списке «Проекты» выберите «Веб-приложение».

3. Нажмите «Далее >». Введите наименование проекта «myblog».

4. Сервер и параметры настройки. Далее Вам необходимо выбрать сервер и версию Java EE платформы. Если в списке серверов нет Вашего сервера, то добавьте его, используя кнопку «Добавить».

После завершения всех настроек нажмите кнопку «Готово».

/> или F6. В результате IDE развернет на выбранном вами сервере данное веб-приложение. Протестить его можно по перейдя по ссылке:

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

Взаимодействие IDE с базой данных

Подключим IDE к нашей базе данных. Для этого выполним простые действия.

1. На вкладке «Службы» кликните правой кнопкой мыши и в появившемся контекстном меню выберите пункт «Зарегистрировать сервер MySQL».

2. По умолчанию имя узла и номер порта сервера совпадают с предложенными. Вам нужно ввести ваше имя пользователя и пароль. Нажмите ОК.

В списке баз данных появится новое подключение. Выполните коннект к ней, используя соответствующий пункт в контекстном меню подключения.

Шаблоны страниц

Далее создадим несколько шаблонов наших страниц. Для этого нажмите на кнопку «Создать файл. » . Выберите тип файла «JSP» и нажмите «Далее. «, введите название страницы Article и нажмите «Готово«. Подобным же образом создайте jsp файл Registration.

Теперь создайте папку «css» в корневом каталоге и добавьте новую каскадную страницу стилей style.

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

Можно посмотреть каждую из страниц, набрав в адресной строке браузера строку типа localhost:8080/article.jsp

Теперь произведем небольшую верстку сайта. Откройте файл index.jsp и добавьте в него следующий код.

Файл article.jsp будет отличать лишь то, что блок article у него будет встречаться единожды, поэтому скопируйте этот же код в файл article.jsp за исключением того, что блог div будет выглядеть вот так:

Файл registration.jsp.

Файл style.css будет содержать следующий код.

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

На этом третья статья серии закончена.

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

Комментарии

12.02.2017Автор: Дмитрий

Здравствуйте, автору спасибо , почему то только нашел ваш сайт. Материалы будут новые?

17.06.2017Автор: Abay

Планирую изучить Java + Web, но тупое копирование кода вряд ли поможет достичь хороших результатов.

Создаём веб-приложение с Java Servlets

  • Переводы, 18 марта 2018 в 14:35
  • Никита Прияцелюк

Одной из самых приятных особенностей Java является её многогранная природа. Конечно, создание традиционных десктопных и даже мобильных приложений — это здорово. Но что, если вы хотите уйти с проторенных дорожек и зайти на территорию разработки web приложений на Java? Для вас есть хорошая новость: в комплекте с языком идёт полноценный Servlet API, который позволяет вам создавать надёжные веб-приложения без особых хлопот.

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

Создание приложений на Java с помощью Servlets

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

Сервлет — классная штука, которая помимо всего прочего может принимать данные от клиента, как правило через GET и POST-запросы, работать с cookie и параметрами сеанса. А ещё она обрабатывает данные через дополнительные уровни приложений и отправляет выходные данные клиенту как в текстовом, так и в бинарном форматах (HTML, XML, PDF, JPG, GIF и т.д.), во многих случаях используя Java Server Pages (JSP) файлы.

Лучше всего начинать работу с сервлетами через конкретный пример. Мы создадим простое веб-приложение, которое позволит клиентам регистрироваться с помощью простой HTML-формы. Данные, предоставленные клиентами, будут собираться сервлетом и проверяться валидаторами.

Разбираемся с конфигурационными файлами

Чтобы вы понимали структуру нашего будущего приложения, вот как она будет выглядеть:

Первым шагом к созданию приложения является определение так называемого дескриптора развёртывания. Он указывает, как приложение должно быть развёрнуто в определенной среде. Когда дело касается веб-приложений, дескриптор развёртывания представляет собой простой XML-файл, называемый web.xml и является частью стандартной спецификации Java EE. В нашем случае он будет выглядеть так:

Как вы видите, web . xml только определяет версию Java Servlet Specification (3.1), которую мы будем использовать в приложении. Разумеется, в нём может быть гораздо больше содержимого, включая директивы сопоставления сервлетов, параметры инициализации, список приветственных файлов и несколько дополнительных настроек. Но чтобы не усложнять процесс разработки, давайте оставим его таким как есть.

LATOKEN, Москва, от 3500 до 5000 $

Так как наше приложение будет использовать Servlet API и Java Servlet Pages (JSP) для отображения данных клиента, нам нужно загрузить все необходимые JAR. Maven сделает за нас трудную работу, вот как будет выглядеть файл POM:

Если говорить просто, pom.xml определяет все зависимости, необходимые для работы с сервлетами: JSP, Java Standard Tag Library (JSTL) и Java Expression Language (JEL).

Итак, мы уже создали конфигурационные файлы приложения. Однако в текущем состоянии оно буквально ничего не делает. Мы хотим, чтобы клиенты могли регистрироваться с помощью HTML-формы, поэтому следующее, что нам нужно сделать, — это создать JSP-файлы, которые будут отображать вышеупомянутую форму и данные клиента после успешного завершения регистрации. Этим мы сейчас и займёмся.

Работаем над внешним видом

Внешний вид приложения будет определяться двумя JSP-файлами — в контексте MVC они называются представлениями. Первый будет отвечать за отображение формы регистрации и возможных ошибок, вызванных после проверки введённых данных. Второй будет обычной страницей приветствия, в которой будут показаны данные, введённые клиентом, после успешного завершения процесса регистрации.

Вот первый JSP-файл:

Файл содержит простой HTML с парочкой дополнений. Вот она, прелесть JSP в сочетании с JSTL и JEL. Обратите внимание на то, как легко проверить наличие ошибок валидации, используя такие стандартные теги, как и .

Атрибут формы регистрации action указывает на следующий URL: $/processcustomer . Это значит, что каждый раз, когда клиент пытается зарегистрироваться, данные будут отправляться в processcustomer независимо от URL, по которому доступна форма. Это достигается за счёт функциональности объектов, доступных из JSP-файла, таких как request .

Скоро мы увидим, как сервлет связывается с URL processcustomer и как он взаимодействует с введёнными данными. А пока давайте посмотрим на JSP-файл, который отвечает за страницу приветствия:

Теперь, когда мы разобрались с отображением страниц, следующим шагом будет создание сервлета, ответственного за сбор данных клиента из POST-запросов и подтверждение данных простым способом.

Пишем контроллер

Написать сервлет, способный получить данные из формы регистрации, проще простого. Всё, что нам нужно сделать, — это написать подкласс для класса HttpServlet и реализовать его методы doGet() или doPost() (или оба, если надо). В данном случае сервлет будет взаимодействовать с данными, поступающими из POST-запросов.

Вот как он выглядит:

Первое, на что здесь стоит обратить внимание, — использование аннотации @WebServlet(name =»CustomerController», urlPatterns = «/processcustomer») . Она говорит контейнеру сервлета использовать класс CustomerController для обработки HTTP-запросов по адресу /processcustomer . Того же эффекта можно достичь путём добавления директив сопоставления сервлетов в web.xml , как здесь, но так как мы используем Servlet Specification 3.1 нам нет необходимости прибегать к такому способу.

Здесь мы назвали сервлет CustomerController , так как считается хорошей практикой использовать имя класса сервлета в качестве значения атрибута name аннотации @WebServlet . В противном случае некоторые контейнеры не смогут выполнить сопоставление, что приведёт к ошибке 404.

Сам класс CustomerController выполняет несколько простых задач. Во-первых, он собирает введённые в форму данные, используя реализацию интерфейса HttpServletRequest , который содержит значения, соответствующие полям firstname , lastname и email формы. Затем он устанавливает эти значения в качестве атрибутов запроса, поэтому их можно повторно отобразить либо в форме, либо на странице с результатами. Наконец, валидаторы проверяют правильность введённых данных.

Валидаторы — это простые классы, которые проверяют определённые свойства, например, является ли строка пустой и выглядит ли email как email. На GitLab автора можно посмотреть на их реализацию.

Результат валидации влияет на дальнейший ход событий: если данные не валидны, клиент перенаправляется через объект RequestDispatcher на страницу регистрации, где отображаются соответствующие ошибки. Если всё в порядке, то отображается страница приветствия.

Итак, мы создали целое веб-приложение на Java, которое позволяет зарегистрировать клиентов с помощью HTML-формы, базового сервлета и нескольких JSP-файлов. Пора его запустить.

Запускаем приложение

Для запуска приложения нужно проделать следующие шаги:

  1. Для начала нам понадобится Git (убедитесь, что скачиваете подходящую версию), Maven и контейнер сервлета (например, Apache Tomcat, Jetty, или JBoss Wildfly). Если что-то из этого уже включено в вашу IDE, то вы можете использовать встроенный вариант.
  2. Используйте Git, чтобы клонировать репозиторий приложения, и импортируйте его в вашу IDE, желательно как проект Maven.
  3. Разверните проект в контейнере сервлета и запустите его. Развёртывание подразумевает создание WAR-файла или exploded WAR и его помещение в папку развёртывания контейнера по умолчанию. Зачастую IDE способна сделать развёртывание за вас, поэтому не перегружайте себя лишней работой и посмотрите документацию вашей IDE (документация для IntelliJ IDEA). Когда вы развернёте проект и запустите его, должен запуститься бразуер по умолчанию с окном регистрации.
  4. Попробуйте заполнить не все поля в форме или вовсе не заполнить их и вы увидите, как поверх соответствующих полей отобразятся ошибки. Введите всё как положено, и вас перенаправит на страницу приветствия.

Заключение

Итак, вы приобрели все навыки, необходимые для создания собственного веб-приложения на Java без необходимости прибегать к сложным фреймворкам. Всё, что вам нужно, — Servlet API, технология вроде JSP для отображения и встроенные средства Java. Здорово, правда?

Стоит отметить, что реализация класса CustomerController подчеркивает достоинства и недостатки сервлетов: с одной стороны, он вкратце показывает, насколько легко обрабатывать параметры запроса и отправлять ответы клиенту в разных форматах. Но эта функциональность имеет свою цену: обе реализации интерфейсов HttpServletResponse и HttpServletResponse являются обычными локаторами служб. Нельзя сказать, что это плохо, поскольку локаторы просто содержат данные. Однако нужно помнить, что эти реализации будут всегда привязаны к сервлету.

WEB приложение на Java

Вы наверняка слышали о том, что сайты можно делать на PHP, Python и довольно не плохие сайты. Но как же Java? Да на java тоже можно делать очень даже офигенные сайты, а если быть точней то используют java для разработки крупных ресурсов. В этом уроке я покажу как создать простое web-приложение на java.

Что нам потребуется для создания web-приложения?

1) Любой сервер приложений в нашем случае это будет Tomcat 7.0.

2) Верная и надежная Intellij IDEA.

3) Желание создать своё первое WEB-приложение.

Шаг 1

Создаем обычный Maven проект, назовем его MyFirstWebProject. Структура проекта следующая:

Давайте теперь разберем структуру проекта: src/java/ servlets – тут будут лежать сервлеты(сервлеты будут рассматриваться в Шаг 2.) src/ resources – тут будут лежать все ресурсные файлы которые буду нужны для проекта. src/ webapp – тут лежат все файлы которые будут использоваться во view (к примеру img, css).

Шаг 2

Теперь разберем что такое Servlet? Servlet – это Java-интерфейс, реализация которого расширяет функциональные возможности сервера. Servlet взаимодействует с клиентами посредством принципа запрос-ответ за частую это запросы GET, POST по протоколу HTTP/HTTPS. Для создания сервлета нам нужно подключить зависимости в Maven.

А также не забудьте указать:

это говорит Maven-у что собирать надо в WEB проект, по умолчанию он собирает jar.

Теперь нужно добавить 2 плагина который позволяет откомпилировать и собрать проект в war архив.

Полный листинг pom.xml:

Теперь создадим класс MyServlet который унаследуем от HttpServlet.

Как вы видите тут есть два метода doPost и doGet, как я уже упоминал сервлеты взаимодействуют с клиентом по средством запрос-ответ, так вот в основном это GET и POST. Внимание! Главное не допускать такую ошибку, что всего есть два метода GET/POST их на самом деле 9, это OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT, PATCH. И так рассмотрим эти методы методы: Как вы уже поняли метод doPost принимает и отправляет посредством запроса POST, doGet по средством запроса GET. У обоих методов есть входящие параметры типы которых – HttpServletRequest и HttpServletResponse. HttpServletRequest request – это запрос со стороны клиента; HttpServletResponse response – это ответ со стороны сервера.

Аннотация @WebServlet(“/s”) указывает на то что данный сервлет будет доступен по адресу /s.

Шаг 3

Не забываем, что метод GET срабатывает когда мы просто заходим по URL на страничку, а пост чаще всего используется при передачи данных с формы, но при условии что метод передачи данных формы указан POST. Создадим “Hello Word”:

response.setContentType(«text/html») – в этой строке мы говорим про то что отображать мы будем страничку как html. PrintWriter out = response.getWriter() – тут мы создаем врайтер который поможет нам осуществить ответ с сервера. out.println(«Hello Word») – ну и отправляем ответ с сервера клиенту.

Шаг 4

Теперь соберите проект в Maven:

Шаг 5

Установка и настройка Tomcat 7.0.

2. Извлекаем с архива;

3. Настроить Intellij IDEA что бы деплоить приложение на сервер с нее.

Нажимаем плюсик выбираем Tomcat Server -> Local после чего нажимаем Configure… и выбираем корневую папку где лежит Tomcat 7.0.

В Startup Page – указываем стартовую страничку загрузки в нашем случае это localhost:8080/s (где s это наш про аннотированиый сервлет).

Дальше заходим во вкладкуDeployment:


И выбираем ваш собранный проект, лежит он в корне проекта в папке target/ .war

Шаг 6

Завяжем на наш сервлет jsp страничку.

Для этого мы должны создать в папке src/main/webapp нашу страничку, в нашем случае это index.jsp.

И теперь с помощью метода GET отправим на нее тот же текст “

Hello World!

Вот так будет выглядеть наш метод сервлета doGet():

С помощью RequestDispatcher мы отправляем наш response request клиенту.

А так будет выглядеть index.jsp

С помощью конструкции $ мы принимаем данные с сервера.

После этого вы получите ту же по виду страничку, только это уже будет не сервлет отображать а jsp.

Для получения углубленных знаний по Java проходите наш курс «Программирование на языке Java для начинающих», а также читайте серию статей «Spring Data JPA. Работа с БД»: часть 1, часть 2 и часть 3

Начало разработки веб-приложений с Java и Spring

В этом цикле статей я опишу процесс разработки веб-приложения на Java и Spring на примере разработки простого интеренет-магазина. Цикл статей разбит таким образом, чтобы в каждой статье описывался процесс работы с одной технологией или с одной группой взаимосвязанных технологий.

Список статей цикла (будет обновляться):

  • Начало разработки веб-приложений с Java и Spring
  • Асинхронные запросы и REST
  • Spring и работа с базами данных
  • Управление доступом в веб-приложениях с Spring Security

Подготовка проекта

Как уже было написано выше, в статье я буду разбирать процесс разработки простого интернет-магазина. Для разработки проекта я буду использовать Spring Boot, поскольку данный фреймворк позволяет разрабатывать приложения со Spring быстро, минимизируя время, затрачиваемое на конфигурирование контекста приложения, и минимизируя возможные конфликты зависимостей.

В рамках данной статьи потребуются следующие зависимости:

  • spring-boot-starter-web в качестве основы веб-приложения на Servlet API
  • spring-boot-starter-thymeleaf для интеграции Thymeleaf в качестве библиотеки шаблонизации
  • spring-boot-starter-test для тестов

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

Код pom.xml и остальных файлов в этой статье преднамеренно минимизирован, полная версия доступна в репозитории.

Разработка веб-приложения с архитектурой MVC

Главный элемент практически любого интернет-магазина — каталог товаров, давайте разработаем страницы списка товаров и описания товара.

Для начала создадим класс, описывающий товар — Product:

В подавляющем большинстве приложений мы получаем данные из источников данных при помощи специальных классов-репозиториев. Для списка товаров мы создадим простой класс-репозиторий, который будет хранить товары в списке:

Аннотация @Repository нужна для автоматической регистрации компонента класса ProductRepository в контексте приложения.

Теперь можем создать контроллер, который будет обрабатывать поступающие запросы — ProductController:

Аннотация @Controller тоже нужна для автоматической регистрации компонента класса ProductController в контексте приложения. Он будет создан и зарегистрирован в контексте автоматически при запуске приложения.

Регистрация компонентов приложения при помощи аннотаций не является самой оптимальной с точки зрения эффективности использования ресурсов, но позволяет конфигурировать контекст приложения более наглядно.

Аннотация @RequestMapping указывает, что данный класс-контроллер обрабатывает HTTP-запросы, путь которых начинается с /catalog/products.

Страница списка товаров

Теперь для страницы списка товаров создадим метод findAll в ProductRepository, который потребуется для получения всех товаров из репозитория:

В классе ProductController создадим метод, который будет обрабатывать запрос на получение страницы списка товаров:

Аннотация @GetMapping указывает, что метод list обрабатывает запросы к сегменту пути list. Полный путь, который обрабатывает этот метод, складывается из пути, указанного в аннотации @RequestMapping класса ProductController, и пути, указанного в @GetMapping метода. Таким образом метод list обрабатывает запросы с путём /catalog/products/list.

Аннотации @GetMapping, @PostMapping и т.д. являются упрощенными альтернативами аннотации @RequestMapping. Таким образом вместо @GetMapping можно написать @RequestMapping(method = RequestMethod.GET)

Метод list возвращает объект класса ModelAndView, который передаёт имя отображаемого шаблона, модель, содержащую список товаров в атрибуте product, и HTTP-статус 200 OK.

Теперь можно создать шаблон страницы. Мы указали, что метод list возвращает шаблон с именем catalog/products/list, соответственно, нам для этого необходимо в директории ресурсов создать структуру директорий templates/catalog/products и файл list.html в ней.

Директория templates в директории ресурсов является директорией по умолчанию для шаблонов в веб-приложениях, использующих Spring Boot. Вместо этой директории можно указать другое место при помощи настроек шаблонизатора, например для Thymeleaf — spring.thymeleaf.prefix

Шаблон страницы будет очень простым и будет содержать список ссылок на страницы товаров:

Вместо специфичных для Thymeleaf аттрибутов используются аттрибуты, начинающиеся с data-th-. Это позволяет не использовать XML-схему Thymeleaf. Например, для генерирования аттрибута href используется data-th-href вместо th:href.

Если мы заполним репозиторий тестовыми данными, запустим приложение (например, при помощи Maven: mvn spring-boot:run) и откроем страницу http://localhost:8080/catalog/products/list, то увидим примерно такую страницу:

Страница со списком товаров

Тестирование

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

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

Библиотека spring-boot-starter-test предоставляет богатый инструментарий для модульного и интеграционного тестирования приложений, использующих Spring. Никаких дополнительных зависимостей нам на данный момент не потребуется.

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

В первую очередь давайте напишем модульный тест для метода list класса ProductController. Поскольку в данном методе отсутствуют ветвления, тест будет очень простой:

Я комментариями разделил код теста на три части: описание исходных условий (given), вызов тестируемого метода (when) и проверку результата (then). Каждый тест имеет минимум две части: вызов и проверку результата.

В части, где описываются исходные условия, я создал мок-объект для класса ProductRepository и указал, что должен вернуть его метод findAll. Я мог бы использовать реальный объект этого класса, но тогда это нарушало бы принцип изолированности тестирования, поскольку тест начал бы зависеть от поведения ProductRepository.

В части, где описываются проверки, я проверил полученный объект класса ModelAndView на соответствие нужным критериям при помощи статических методов класса Assert и проверил, что был вызван метод ProductRepository.findAll() при помощи метода Mockito.verify().

На этом написание модульного теста завершено. Если мы запустим тест, то он должен завершиться успешно. Теперь можно перейти к написанию интеграционного теста. В нём мы будем тестировать HTTP-вызов к нашему веб-приложению и проверять полученный ответ. Заготовка класса интеграционных тестов для приложения на основе Spring Boot выглядит следующим образом:

Для интеграционного тестирования нам понадобится MockMvс, при помощи которого будут имитироваться HTTP-вызовы к приложению. Мы можем создать этот объект самостоятельно, а можем отметить класс ProductControllerIntegrationTest аннотацией @AutoConfigureMockMvc, а затем внедрить объект класса MockMvc через свойство при помощи аннотации @Autowired. Аналогично нему мы внедрим объект класса ProductRepository, чтобы в рамках интеграционного теста можно было наполнить репозиторий тестовыми данными, но для него будем использовать аннотацию @SpyBean, которая позволит отслеживать вызовы его методов.

На практике лучше предпочитать внедрение зависимости через конструктор или set-метод вместо внедрения через свойство. Но при написании тестов допустимо внедрение зависимостей и через свойство.

Теперь в тестовом методе при помощи объекта класса MockMvc мы можем сымитировать HTTP-вызов и проверить валидность ответа от приложения. Интеграционный тест будет выглядеть следующим образом:

Как и в случае с модульным тестом, код разделён на все те же три части: исходные условия, обращение к тестируемому методу и проверка результата. Обращу внимание на то, что для XPath-проверок требуется, чтобы возвращённая страница была XML-валидной, иначе будет выброшена ошибка, связанная с парсингом документа.

Если требуется более детальное тестирование HTML-страниц, то лучше обратиться к WebDriver или HtmlUnit, для которых предусмотрена интеграция с MockMvc.

Я преднамеренно не стал описывать тесты для ProductRepository, так как этот класс существует только в качестве примера. Тесты репозиториев будут описаны в одной из следующих статей, в которых речь пойдёт о работе с реальными базами данных.

Страница с описанием товара

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

Написание тестов

Логичнее начать с написания интеграционного теста, так как им мы охватываем сразу все компоненты приложения, задействованные при обработке вызова. Более того, условия прохождения интеграционных тестов описываются более «человеческим» языком, чем условия модульных тестов.

Обработка запроса на получение страницы с описанием товара может пойти по двум сценариями, и мы можем их описать:

  1. Если товар с запрашиваемым идентификатором существует, то должна быть отображена страница с описанием товара и со статусом 200 OK
  2. Если товар с запрашиваемым идентификатором не существует, то должна быть отображена страница с ошибкой и со статусом 404 Not Found

Мы можем протестировать оба сценария в одном тестовом методе, но удобнее будет написать для каждого сценария отдельный тестовый метод. Предполагается, что наш будущий метод должен обратиться к репозиторию ProductRepository для получения товара по идентификатору и, в зависимости от результата, вернуть соответствующую страница. Код тестовых методов будет выглядеть следующим образом:

Я вынес заполнение репозитория ProductRepository в отдельный метод, отмеченный аннотацией @Before, чтобы избежать дублирования кода. Теперь перед вызовом каждого тестового метода репозиторий будет заново заполняться тестовыми данными.

После написания интеграционных тестов код проекта стал не компилируемым, так как у класса ProductRepository нет метода findOneById. Таким образом мы определили будущую функциональность при помощи тестов.

Теперь пришло время написать модульные тесты, как и в случае с интеграционными их будет тоже два:

Я вынес объекты ProductRepository и ProductController в свойства класса ProductControllerTest, так как они используются во всех тестах. Кроме этого я решил использовать Optional, вместо проверок на null.

Реализация

Теперь можно правильно реализовать метод product в классе ProductController, после чего код должен стать снова компилируемым, а тесты проходить успешно.

Для доступа к переменной в пути используется аннотация @PathVariable, обратите внимание на то, что имя аргумента метода должно соответствовать имени, указанному в плейсхолдере пути, иначе его нужно указать в аттрибуте name аннотации @PathVariable.

И для прохождения интеграционных тестов необходимо создать два простых шаблона:

Теперь мы можем снова запустить приложение и перейти со страницы списка товаров на страницу описания конкретного товара.

Страница с описанием продукта

Читать еще:  Можно ли как то восстановить переписку вконтакте
Ссылка на основную публикацию
Adblock
detector