Топ-100Валидация форм в Spring MVC - CodOrbits
LogoCodOrbits

Раздел: Spring MVC

Раздел расскажет о Spring MVC — компоненте Spring для разработки веб-приложений с использованием архитектуры MVC.

Все разделы
Иконка Spring MVC

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

Last updated: 11 мая 2025 г.

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

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

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

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

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

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

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

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

1package classes;
2
3import java.util.LinkedHashMap;
4
5@Component
6public class SomeUser {
7
8    // Ниже используются аннотации валидации над полем.
9    // В нашем приложении текстовое поле формы будет связано
10    // с полем userName объекта в аттрибуте.
11    // Если поле помечено @NotNull значит оно будет проверяться
12    // на пустоту при отправке формы. То есть, если пользователь
13    // ничего не ввел в текстовое поле, которое связано с полем
14    // userName и отправил форму, то отправка формы не будет
15    // успешной, пока пользователь не введет значение
16    // в текстовое поле.
17    // message — это сообщение, которое будет
18    // показано пользователю, если он не ввел ничего в поле.
19    // С помощью @Size можно указать минимальное количество
20    // символов, которые пользователь должен ввести
21    // в текстовое поле.
22    @NotNull(message = "field is required!!!")
23    @Size(min = 5, message = "field is required!!!")
24    private String userName;
25    
26    private String userCountry;
27    private String userLanguage;
28    private String[] userBrowser;
29
30    // Также форма будет содержать текстовое поле, которое
31    // будет связано с полем userAge объекта в атрибуте.
32    // С помощью @Min задаем минимальное число, которое
33    // можно указать в текстовом поле.
34    // С помощью @Max задаем максимальное число, которое
35    // можно указать в текстовом поле.
36    @Min(value = 0, message = "must be more than 0")
37    @Max(value = 100, message = "must be less than 100")
38    private Integer userAge;
39
40    // Также форма будет содержать текстовое поле, которое
41    // будет связано с полем userEmail объекта в атрибуте.
42    // С помощью @Pattern можно задать регулярное выражение,
43    // по которому будет проверяться содержимое текстового
44    // поля. Регулярные выражения мы пока не проходили.
45    // Но если вкратце, то это некоторое правило
46    // (оно может быть достаточно сложным), по которому
47    // валидируется содержимое поля.
48    // В нашем случае мы задали, что текстовое поле должно
49    // содержать 30 символов и может содержать
50    // такие-то символы.
51    @Pattern(regexp = "^[a-zA-Z0-9]{30}", message = "must be 30 characters")
52    private String userEmail;
53
54    public SomeUser() { }
55
56    public String getUserName() {
57        return userName;
58    }
59
60    public void setUserName(String userName) {
61        this.userName = userName;
62    }
63
64    public String getUserCountry() {
65        return userCountry;
66    }
67
68    public void setUserCountry(String userCountry) {
69        this.userCountry = userCountry;
70    }
71
72    public String getUserLanguage() {
73        return userLanguage;
74    }
75
76    public void setUserLanguage(String userLanguage) {
77        this.userLanguage = userLanguage;
78    }
79
80    public String[] getUserBrowser() {
81        return userBrowser;
82    }
83
84    public void setUserBrowser(String[] userBrowser) {
85        this.userBrowser = userBrowser;
86    }
87
88    public Integer getUserAge() {
89        return userAge;
90    }
91
92    public void setUserAge(Integer userAge) {
93        this.userAge = userAge;
94    }
95
96    public String getUserEmail() {
97        return userEmail;
98    }
99
100    public void setUserEmail(String userEmail) {
101        this.userEmail = userEmail;
102    }
103}

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

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

1<%@ page language="java" contentType="text/html;
2    charset=ISO-8859-1"
3    pageEncoding="ISO-8859-1"%>
4<%@ taglib prefix="form"
5    uri="http://www.springframework.org/tags/form"%>
6<%@ page isELIgnored="false" %>
7<!DOCTYPE html>
8<html>
9<head>
10<meta charset="ISO-8859-1">
11<title>Insert title here</title>
12<style>.ErrorClass{color:blue}</style>
13</head>
14<body>
15<form:form action="FormValidProcessor" modelAttribute="someuser">
16    username: <form:input path="userName"/>
17    <!-- form:errors - тег сообщения об ошибке если ввели не
18    правильные данные. в path переменная (точнее часть имени
19    геттера сеттера переменной как мы помним) в аттребуте, к
20    которой применяется валидация.
21    cssClass - оформление сообщения об ошибке. То есть как то что
22    мы писали в message (а там как мы помним мы писали сообщение
23    об ошибке) в классе SomeUser будет оформлено. ErrorClass
24    это имя css класса его можно найти выше в теге style. -->
25    <form:errors path="userName" cssClass="ErrorClass"/> <br/>
26    <!-- для min, max аннотаций. -->
27    Age: <form:input path="userAge"/>
28    <form:errors path="userAge" cssClass="ErrorClass"/> <br/>
29    <!-- для pattern аннотаций для регулярных выражений. -->
30    Email: <form:input path="userEmail"/>
31    <form:errors path="userEmail" cssClass="ErrorClass"/> <br/>
32    <input type="submit" value="submit"/> <br/>
33</form:form>
34</body>
35</html>

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

1package classes;
2
3import javax.servlet.http.HttpServletRequest;
4
5@Controller
6@RequestMapping("/FirstController")
7public class MVCcontroller {
8
9    @RequestMapping("/FirstJSP")
10    public String FirstJSP() {
11        return "JSPpage";
12    }
13
14    @RequestMapping("/SecondJSP")
15    public String SecondJSP() {
16        return "JSPpage1";
17    }
18
19    @RequestMapping("/FormPage")
20    public String FormPage() {
21        return "FormPage";
22    }
23
24    @RequestMapping("/FormProcessingController")
25    public String FormProcessingController(
26            HttpServletRequest req, Model model) {
27        model.addAttribute("resposeMsg",
28                (req.getParameter("username") + " entered!"));
29        return "FormProcessingPage";
30    }
31
32    @RequestMapping("/FormTagPage")
33    public String FormTagPage(Model model) {
34        model.addAttribute("someuser", new SomeUser());
35        return "FormTagPage";
36    }
37
38    @RequestMapping("/FormTagProcessor")
39    public String FormTagProcessor(
40            @ModelAttribute("username") SomeUser someUser) {
41        System.out.println(someUser.getUserName());
42        System.out.println(someUser.getUserCountry());
43        System.out.println(someUser.getUserLanguage());
44        System.out.println(someUser.getUserBrowser());
45        return "FormTagProcessingPage";
46    }
47
48    // Новый обработчик
49    // он просто переводит на страницу с формой,
50    // которая будет валидироваться.
51    @RequestMapping("/FormValidPage")
52    public String FormValidPage(Model model) {
53        model.addAttribute("someuser", new SomeUser());
54        return "FormValidPage";
55    }
56
57    // Новый обработчик
58    @RequestMapping("/FormValidProcessor")
59    // аннотацией @Valid указываем что пришедший атрибут
60    // из формы в обработчик подлежит валидации и в нем
61    // будут проверены поля с аннотациями валидации
62    public String FormValidProcessor(
63            @Valid @ModelAttribute("someuser") SomeUser someUser,
64            BindingResult mybindingResult) {
65        // Результат же валидации атрибута
66        // записывается в mybindingResult.
67
68        // проверяем bindingResult на наличие ошибок валидации
69        if (mybindingResult.hasErrors()) {
70            // если есть ошибки валидации отправляем уже
71            // валидированный атрибут обратно в форму где
72            // ошибка валидации будет отображена тегом form:errors
73            return "FormValidPage";
74        } else {
75            // если их нет то отправляем атрибут
76            // на результирующую страницу где из него
77            // выведем содержимое нужной переменной
78            return "FormValidProcessingPage";
79        }
80    }
81}

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

1<%@ page language="java" contentType="text/html;
2    charset=ISO-8859-1"
3    pageEncoding="ISO-8859-1"%>
4<%@ page isELIgnored="false"%>
5<!DOCTYPE html>
6<html>
7<head>
8    <title>Auth Form</title>
9</head>
10<body>
11    <h2>${someuser.userName}</h2>
12    <h2>${someuser.userAge}</h2>
13    <h2>${someuser.userEmail}</h2>
14</body>
15</html>

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

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

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

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

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

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

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

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

Вот так:

Нажимаем Submit:

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

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

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


Следующие уроки

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

20
мин.

Similar Articles Icon
Divider

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

17
мин.

Similar Articles Icon
Divider

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

16
мин.

Similar Articles Icon