Що означає анотація @Valid навесні?


87

У наступному прикладі ScriptFileпараметр позначений @Validанотацією.

Що робить @Validанотація?

@RequestMapping(value = "/scriptfile", method = RequestMethod.POST)    
public String create(@Valid ScriptFile scriptFile, BindingResult result, ModelMap modelMap) {    
    if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");        
    if (result.hasErrors()) {        
        modelMap.addAttribute("scriptFile", scriptFile);            
        modelMap.addAttribute("showcases", ShowCase.findAllShowCases());            
        return "scriptfile/create";            
    }        
    scriptFile.persist();        
    return "redirect:/scriptfile/" + scriptFile.getId();        
}    

Відповіді:


63

Це для цілей перевірки.

Перевірка Загальноприйнятою є перевірка моделі після прив’язки введення користувачем до неї. Spring 3 забезпечує підтримку декларативної перевірки за допомогою JSR-303. Ця підтримка вмикається автоматично, якщо на шляху до вашого курсу присутній постачальник послуг JSR-303, наприклад Hibernate Validator. Якщо увімкнено, ви можете запускати перевірку, просто анотуючи параметр методу Controller анотацією @Valid: Після прив’язки вхідних параметрів POST, AppointingForm буде перевірено; у цьому випадку для перевірки значення поля дати не є нульовим і відбувається в майбутньому.


Подивіться тут для отримання додаткової інформації:
http://blog.springsource.com/2009/11/17/spring-3-type-conversion-and-validation/


36

Додаючи до вищезазначених відповідей, погляньте на наступні. AppointmentForm«S dateстовпець позначається парою анотацій. Маючи @Validанотацію, яка запускає перевірку на AppointmentForm(у даному випадку @NotNullі @Future). Ці анотації можуть надходити від різних постачальників JSR-303 (наприклад, Hibernate, Spring..etc).

    @RequestMapping(value = "/appointments", method = RequestMethod.POST)
    public String add(@Valid AppointmentForm form, BindingResult result) {
        ....
    }

    static class AppointmentForm {

        @NotNull @Future
        private Date date;
    }

1
У мене є подібний код. Я видалений @Validвід ApplicationFormпараметра , але, по- як і раніше валідації були випущені на date(набір в null) поле. Будь ласка, поясніть.
lupchiazoem

17

IIRC @Valid - це не анотація Spring, а анотація JSR-303 (що є стандартом Bean Validation). Що він робить, це в основному перевіряє, чи дані, які ви надсилаєте в метод, є дійсними чи ні (це перевірить для вас scriptFile).


2
Що означає "він перевірить для вас файл script"? Перевірте, чи не є він нульовим, має якийсь синтаксис чи якийсь вміст? Іншими словами, що це перевіряє і як? Чи повинен користувач щось реалізовувати? Де я можу отримати інформацію про це? Дякую!
nephewtom

Будь ласка, дайте відповідь на запитання @ nephewtom, цього недостатньо для підтвердження з відсутнім головним пунктом, який "проти чого"?
монамі

17

@Validсаме по собі не має нічого спільного з Весною. Це частина специфікації Bean Validation (їх декілька, остання - JSR 380 станом на другу половину 2017 року), але @Validдуже стара і походить від JSR 303.

Як ми всі знаємо, Spring дуже добре забезпечує інтеграцію з усіма різними JSR та бібліотеками Java загалом (згадайте JPA, JTA, Caching тощо), і, звичайно, ці хлопці подбали і про перевірку. Одним з ключових компонентів, що сприяє цьому, є MethodValidationPostProcessor .

Спроба відповісти на ваше запитання - @Validдуже зручна для так званої каскадної перевірки, коли ви хочете перевірити складний графік, а не лише елементи верхнього рівня об’єкта. Кожен раз, коли ви хочете заглибитися, ви повинні використовувати @Valid. Ось що диктує JSR. Spring буде відповідати цьому з деякими незначними відхиленнями (наприклад, я спробував застосувати @Validatedзамість @Validметоду RestController і роботи з перевірки, але те ж саме не застосовуватиметься до звичайних "службових" компонентів).


Але що підтверджує?
nephewtom

Будь ласка, детальніше розробіть, @nephewtom. Що ви хочете уточнити?
yuranos

Я прочитав JSR 303: Перевірка компонента , beanvalidation.org/1.0/spec, але я все ще не розумію, для чого буде виконуватися перевірка ScriptFile scriptFile.
nephewtom

ScriptFile всередині нього, мабуть, має купу полів, і на них також є анотації. Тут починається перевірка. Виходячи з оригінального запитання, незрозуміло, що саме знаходиться в класі ScriptFile.
yuranos

Добре, дякую. Не могли б ви навести приклад того, що може перевірити, якщо його поля містять String, Integer і Bean?
nephewtom

2
public String create(@Valid @NotNull ScriptFile scriptFile, BindingResult result, ModelMap modelMap) {    
    if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");        

Я думаю, ця @NotNullанотація є дійсною, тому якщо умова не потрібна.


1

Просто додавши до вищезазначеної відповіді, у веб-застосунку @validвикористовується, де компонент, що перевіряється, також анотується анотаціями перевірки, наприклад @NotNull, @Email(анотація сплячого режиму), тому, отримуючи вхідні дані від користувача, значення можуть бути перевірені, а результат прив’язки матиме перевірку результати. bindingResult.hasErrors()повідомить, чи не вдалося перевірити.


1

Інший зручний аспект @Valid, про який не згадувалося вище, полягає в тому, що (тобто: за допомогою Postman для тестування кінцевої точки) @Valid відформатує вихід неправильного виклику REST у відформатований JSON замість краплини ледве читабельного тексту. Це дуже корисно, якщо ви створюєте комерційно споживаний API для своїх користувачів.


1

Здається, я знаю, куди прямує ваше запитання. І оскільки це запитання з’являється в основних результатах пошуку Google, я можу дати чітку відповідь на те, що робить анотація @Valid.

Я представлю 3 сценарії того, як я використовував @Valid

Модель:

public class Employee{
private String name;
@NotNull(message="cannot be null")
@Size(min=1, message="cannot be blank")
private String lastName;
 //Getters and Setters for both fields.
 //...
}

JSP:

...
<form:form action="processForm" modelAttribute="employee">
 <form:input type="text" path="name"/>
 <br>
 <form:input type="text" path="lastName"/>
<form:errors path="lastName"/>
<input type="submit" value="Submit"/>
</form:form>
...

Контролер для сценарію 1:

     @RequestMapping("processForm")
        public String processFormData(@Valid @ModelAttribute("employee") Employee employee){
        return "employee-confirmation-page";
    }

У цьому випадку після надсилання форми з порожнім полем lastName ви отримаєте сторінку з помилкою, оскільки ви застосовуєте правила перевірки, але ви не обробляєте її взагалі.

Приклад зазначеної помилки: Сторінка винятку

Контролер для сценарію 2:

 @RequestMapping("processForm")
    public String processFormData(@Valid @ModelAttribute("employee") Employee employee,
BindingResult bindingResult){
                return bindingResult.hasErrors() ? "employee-form" : "employee-confirmation-page";
            }

У цьому сценарії ви передаєте всі результати цієї перевірки до bindingResult, тож вам вирішувати, що робити з результатами перевірки цієї форми.

Контролер для сценарію 3:

@RequestMapping("processForm")
    public String processFormData(@Valid @ModelAttribute("employee") Employee employee){
                return "employee-confirmation-page";
            }
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, String> invalidFormProcessor(MethodArgumentNotValidException ex){
  //Your mapping of the errors...etc
}

У цьому сценарії ви все ще не обробляєте помилки, як у першому сценарії, але передаєте це іншому методу, який подбає про виняток, який @Valid запускає під час обробки моделі форми. Перевірте це, щоб побачити, що робити з картографуванням та ін.

Підводячи підсумок : @Valid сам по собі, не роблячи нічого більше, що ініціює перевірку валідації Коментовані поля JSR 303 ( @NotNull, @Email, @Size тощо ), вам все одно потрібно вказати стратегію, що робити з результатами зазначеної перевірки.

Сподіваюся, я зміг зрозуміти щось для людей, які можуть зіткнутися з цим.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.