Валидация форм в Spring MVC

Валидация – это проверка данных формы на то подходят ли они под какие-то условия.

Для начала необходимо скачать hibernate validator.

Можно скачать по ссылке https://hibernate.org/validator/releases/6.2/. Потом закидываем в lib jar файлы из папки dist и required.

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

Давайте теперь дополним класс SomeUser. В этом классе создадим два новых поля и сгенерируем геттеры сеттеры для них. Эти новые поля будут связаны со своим текстовым полем в форме.

Содержимое этих полей будет валидироваться в соответствии с указанными аннотациями над этими полями.

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

Итак разберем аннотации валидации:

package classes; import java.util.LinkedHashMap; @Component public class SomeUser { // Ниже используются аннотации валидации над полем. // В нашем приложении текстовое поле формы будет связано // с полем userName объекта в аттрибуте. // Если поле помечено @NotNull значит оно будет проверяться // на пустоту при отправке формы. То есть, если пользователь // ничего не ввел в текстовое поле, которое связано с полем // userName и отправил форму, то отправка формы не будет // успешной, пока пользователь не введет значение // в текстовое поле. // message — это сообщение, которое будет // показано пользователю, если он не ввел ничего в поле. // С помощью @Size можно указать минимальное количество // символов, которые пользователь должен ввести // в текстовое поле. @NotNull(message = “field is required!!!”) @Size(min = 5, message = “field is required!!!”) private String userName; private String userCountry; private String userLanguage; private String[] userBrowser; // Также форма будет содержать текстовое поле, которое // будет связано с полем userAge объекта в атрибуте. // С помощью @Min задаем минимальное число, которое // можно указать в текстовом поле. // С помощью @Max задаем максимальное число, которое // можно указать в текстовом поле. @Min(value = 0, message = “must be more than 0”) @Max(value = 100, message = “must be less than 100”) private Integer userAge; // Также форма будет содержать текстовое поле, которое // будет связано с полем userEmail объекта в атрибуте. // С помощью @Pattern можно задать регулярное выражение, // по которому будет проверяться содержимое текстового // поля. Регулярные выражения мы пока не проходили. // Но если вкратце, то это некоторое правило // (оно может быть достаточно сложным), по которому // валидируется содержимое поля. // В нашем случае мы задали, что текстовое поле должно // содержать 30 символов и может содержать // такие-то символы. @Pattern(regexp = “^[a-zA-Z0-9]{30}”, message = “must be 30 characters”) private String userEmail; public SomeUser() { } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserCountry() { return userCountry; } public void setUserCountry(String userCountry) { this.userCountry = userCountry; } public String getUserLanguage() { return userLanguage; } public void setUserLanguage(String userLanguage) { this.userLanguage = userLanguage; } public String[] getUserBrowser() { return userBrowser; } public void setUserBrowser(String[] userBrowser) { this.userBrowser = userBrowser; } public Integer getUserAge() { return userAge; } public void setUserAge(Integer userAge) { this.userAge = userAge; } public String getUserEmail() { return userEmail; } public void setUserEmail(String userEmail) { this.userEmail = userEmail; } }

Давайте теперь свяжем новые поля в объекте в аттрибуте username c новыми тегами в форме на странице. Также с помощью тега form:errors будут выводиться сообщения, которые мы писали в message в классе у полей. Этот тег пишем там, где должно появляться это сообщение на странице.

Страница с формой:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <%@ page isELIgnored="false" %> Insert title here username:
Age:
Email:

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

package classes; import javax.servlet.http.HttpServletRequest; @Controller @RequestMapping(“/FirstController”) public class MVCcontroller { @RequestMapping(“/FirstJSP”) public String FirstJSP() { return “JSPpage”; } @RequestMapping(“/SecondJSP”) public String SecondJSP() { return “JSPpage1”; } @RequestMapping(“/FormPage”) public String FormPage() { return “FormPage”; } @RequestMapping(“/FormProcessingController”) public String FormProcessingController( HttpServletRequest req, Model model) { model.addAttribute(“resposeMsg”, (req.getParameter(“username”) + ” entered!”)); return “FormProcessingPage”; } @RequestMapping(“/FormTagPage”) public String FormTagPage(Model model) { model.addAttribute(“someuser”, new SomeUser()); return “FormTagPage”; } @RequestMapping(“/FormTagProcessor”) public String FormTagProcessor( @ModelAttribute(“username”) SomeUser someUser) { System.out.println(someUser.getUserName()); System.out.println(someUser.getUserCountry()); System.out.println(someUser.getUserLanguage()); System.out.println(someUser.getUserBrowser()); return “FormTagProcessingPage”; } // Новый обработчик // он просто переводит на страницу с формой, // которая будет валидироваться. @RequestMapping(“/FormValidPage”) public String FormValidPage(Model model) { model.addAttribute(“someuser”, new SomeUser()); return “FormValidPage”; } // Новый обработчик @RequestMapping(“/FormValidProcessor”) // аннотацией @Valid указываем что пришедший атрибут // из формы в обработчик подлежит валидации и в нем // будут проверены поля с аннотациями валидации public String FormValidProcessor( @Valid @ModelAttribute(“someuser”) SomeUser someUser, BindingResult mybindingResult) { // Результат же валидации атрибута // записывается в mybindingResult. // проверяем bindingResult на наличие ошибок валидации if (mybindingResult.hasErrors()) { // если есть ошибки валидации отправляем уже // валидированный атрибут обратно в форму где // ошибка валидации будет отображена тегом form:errors return “FormValidPage”; } else { // если их нет то отправляем атрибут // на результирующую страницу где из него // выведем содержимое нужной переменной return “FormValidProcessingPage”; } } }

На странице на которую перенаправляет пользователя обработчик (если данные в объекте из аттрибута оказались валидными) извлечем выбранные пользователем значения из объекта в аттрибуте username.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ page isELIgnored="false"%> Auth Form

${someuser.userName}

${someuser.userAge}

${someuser.userEmail}

Перейдем на страницу с формой через обработчик по пути /FormValidPage. Первое текстовое поле давайте оставим пустым, во втором введем число 144, в третьем введем меньше 30 символов.

и после нажатия Submit:

Видим, что вывелись сообщения, которые мы писали в message в аннотациях о том, что пользователь ввел неверные данные. О том, что пользователь оставил поле пустым, а оно не должно быть пустым, о том, что он ввел число выше ста и о том, что поле должно содержать ровно 30 символов.

То есть очевидно аннотации NotNull, Max и Pattern работают.

Давайте теперь проверим аннотации Size и Min. Введем в перовое поле меньше 5 символов, а во второе поле число меньше 0.

После нажатия Submit:

Видим, что сообщения, которые мы писали в аннотациях Size и Min вывелись.  Значит, что аннотации работают.      

Теперь давайте введем правильные данные, то есть в перове поле больше 5 букв, во второе поле число между 0 и 100, в третье поле ровно 30 символов.  

Вот так:

Нажимаем Submit:

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

Это были основные аннотации валидации. Есть и другие конечно.

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

Введение в ORM с использованием Hibernate

Основы ORM с Hibernate: сохранение объектов в БД, настройка проекта, аннотации @Entity и @Table. Практический пример работы с сессиями, транзакциями и маппингом сущностей.
Time to read: 20

Обзор языка запросов HQL в Hibernate

Изучите HQL в Hibernate: объектно-ориентированный язык запросов для работы с БД через классы. Примеры запросов, сравнение с SQL и практическое применение в Java-приложениях.
Time to read: 17

HQL: обновление данных (Update)

Обновление данных в Hibernate через изменение объектов и HQL-запросы. Примеры работы с методами update и executeUpdate для модификации записей.
Time to read: 16