Статьи

Spring MVC: валидатор и @InitBinder

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

Использование Spring MVC Validator

Проверка имеет смысл во времени, когда вы получаете какие-то данные от пользователей. Очевидный способ сделать это — использовать веб-формы. Интерфейс Validator — это средство для реализации логики валидации всего приложения Spring MVC. Звучит многообещающе.

Есть три вещи, которые вам нужно сделать, чтобы начать использовать Валидатор:

  • Создайте класс валидатора для некоторой модели предметной области и добавьте интерфейс валидатора.
  • Перегрузка поддерживает (Class clazz) метод.
  • Метод проверки перегрузки (цель объекта, ошибки ошибок).

Теперь вы знаете основы использования интерфейса Validator . Достаточно теории, давайте продолжим практику.

Пример Vlidator Spring MVC

Я хочу продемонстрировать интерфейс Validator в действии на одном из моих предыдущих учебных пособий, где проверка не будет избыточной. Я имею в виду пример приложения с Spring Data . Сначала вам нужно обновить файл pom.xml, добавив следующую зависимость:

01
02
03
04
05
06
07
08
09
10
11
12
...
        <dependency>
            <groupid>javax.validation</groupid>
            <artifactid>validation-api</artifactid>
            <version>1.0.0.GA</version>
        </dependency>
        <dependency>
            <groupid>org.hibernate</groupid>
            <artifactid>hibernate-validator</artifactid>
            <version>4.3.0.Final</version>
        </dependency>
...

В проекте у меня есть один POJO:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Entity 
    @Table(name = "shops"
    public class Shop { 
 
        @Id 
        @GeneratedValue 
        private Integer id; 
 
        private String name; 
 
        @Column(name = "employees_number"
        private Integer emplNumber; 
 
        public Integer getId() { 
            return id; 
        
 
        public void setId(Integer id) { 
            this.id = id; 
        
 
        public String getName() { 
            return name; 
        
 
        public void setName(String name) { 
            this.name = name; 
        
 
        public Integer getEmplNumber() { 
            return emplNumber; 
        
 
        public void setEmplNumber(Integer emplNumber) { 
            this.emplNumber = emplNumber; 
        
    }

Итак, давайте создадим правила проверки для него:

  • «Имя» не может быть пустым.
  • «EmplNumber» не может быть пустым.
  • «EmplNumber» не может быть меньше 1.

Класс проверки для этих целей будет выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
 
import com.spr.model.Shop;
 
@Component
public class ShopValidator implements Validator {
 
    private final static String EMPLOYEES_NUMBER = "emplNumber";
 
    @Override
    public boolean supports(Class clazz) {
        return Shop.class.isAssignableFrom(clazz);
    }
 
    @Override
    public void validate(Object target, Errors errors) {
        Shop shop = (Shop) target;
 
        Integer emplNumber = shop.getEmplNumber();
 
        ValidationUtils.rejectIfEmpty(errors, "name", "shop.name.empty");
        ValidationUtils.rejectIfEmpty(errors, EMPLOYEES_NUMBER, "shop.emplNumber.empty");
 
        if (emplNumber != null && emplNumber < 1)
            errors.rejectValue(EMPLOYEES_NUMBER, "shop.emplNumber.lessThenOne");
 
    }
 
}

Обратите внимание, что я применил аннотацию @Component к классу, потому что я планирую внедрить ее позже в ShopController. Вот объяснение методов валидатора:

support (Class) — может ли этот валидатор проверять экземпляры предоставленного класса? validate (Object, org.springframework.validation.Errors) — проверяет указанный объект и в случае ошибок проверки регистрирует их с данным объектом Errors. Для получения дополнительной информации посмотрите javadoc класса ValidationUtils . Сообщения, которые будут показаны во время проверки, должны быть помещены в файл «messages.properties»:

1
2
3
shop.name.empty = The "Shop name" field can't be empty.
shop.emplNumber.empty = The "Employees number" field can't be empty.
shop.emplNumber.lessThenOne = The number of employees can't be less then 1.

Давайте перейдем к коду контроллера:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
...
    @Autowired
    private ShopValidator shopValidator;
 
    @InitBinder
    private void initBinder(WebDataBinder binder) {
        binder.setValidator(shopValidator);
    }
...
    @RequestMapping(value="/create", method=RequestMethod.POST)
    public ModelAndView createNewShop(@ModelAttribute @Valid Shop shop,
            BindingResult result,
            final RedirectAttributes redirectAttributes) {
 
        if (result.hasErrors())
            return new ModelAndView("shop-new");
 
        ModelAndView mav = new ModelAndView();
        String message = "New shop "+shop.getName()+" was successfully created.";
 
        shopService.create(shop);
        mav.setViewName("redirect:/index.html");
 
        redirectAttributes.addFlashAttribute("message", message);  
        return mav;    
    }
...

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

  • Автопроводка валидатора.
  • Добавление валидатора в InitBinder .
  • Примените аннотацию @Valid к модели в конкретном контроллере.

И, наконец, давайте посмотрим на JSP:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
...
<h1>New Shop page</h1>
<form:form method="POST" commandname="shop" action="${pageContext.request.contextPath}/shop/create.html">
<table>
<tbody>
<tr>
<td>Shop name:</td>
<td><form:input path="name"></form:input></td>
<td><form:errors path="name" cssstyle="color: red;"></form:errors></td>
</tr>
<tr>
<td>Employees number:</td>
<td><form:input path="emplNumber"></form:input></td>
<td><form:errors path="emplNumber" cssstyle="color: red;"></form:errors></td>
</tr>
<tr>
<td><input value="Create" type="submit"></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</form:form>
...

Обратите внимание на форму: теги ошибок, они отвечают за отображение сообщений об ошибках.

Весна-MVC-валидатор

Резюме

Интерфейс Validator позволяет создавать гибкий уровень проверки для каждого объекта модели домена в вашем приложении. Это хорошая альтернатива стандартным аннотациям валидации JSR-303, таким как @Min, @Max, @NotNull, @Size и т. Д. Полную версию примера можно найти на GitHub .

Ссылка: Spring MVC: Validator и @InitBinder от нашего партнера по JCG Алексея Зволинского в блоге заметок Фрузенштейна .