@Valid注释在Spring中表示什么?


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();        
}    

Answers:


63

这是出于验证目的。

验证在将用户输入绑定到模型之后,通常会对其进行验证。Spring 3支持使用JSR-303进行声明式验证。如果您的类路径中存在JSR-303提供程序(例如Hibernate Validator),则会自动启用此支持。启用后,您可以简单地通过使用@Valid注释对Controller方法参数进行注释来触发验证。在这种情况下,要验证日期字段值不为null并在将来发生。


在这里查看更多信息:http :
//blog.springsource.com/2009/11/17/spring-3-type-conversion-and-validation/


36

除了上述答案外,还请查看以下内容。AppointmentFormdate列中带有几个注释。通过具有@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
我有一个类似的代码。我删除@ValidApplicationForm参数,但仍然在date(设置为null)字段上进行了验证。请解释。
lupchiazoem

17

IIRC @Valid不是Spring注释,而是JSR-303注释(这是Bean验证标准)。它的作用是基本上检查您发送给该方法的数据是否有效(它将为您验证scriptFile)。


2
“它将为您验证scriptFile”是什么意思?检查它是否不为null,是否具有某些语法或某些内容?换句话说,它验证什么以及如何验证?用户应该实施一些东西吗?我在哪里可以获得有关它的信息?谢谢!
nephewtom

请回答@nephewtom的问题,这是不足以验证缺少的要点“反对什么”的答案吗?
蒙纳米

17

@Valid本身与Spring无关。它是Bean验证规范的一部分(有多个规范,最新的是2017年下半年的JSR 380),但是@Valid它非常古老并且从JSR 303一直衍生而来。

众所周知,Spring非常擅长提供与所有不同的JSR和Java库(例如JPA,JTA,Caching等)的集成,当然,这些人也负责验证。MethodValidationPostProcessor是促成此目的的关键组件之一

尝试回答您的问题-@Valid当您要验证复杂的图形而不仅仅是对象的顶级元素时,对于所谓的验证级联非常方便。每次您想深入了解时,都必须使用@Valid。这就是JSR的要求。Spring会遵循一些较小的偏差(例如,我尝试放置@Validated而不是@Valid使用RestController方法并进行验证,但是对于常规的“服务” Bean而言,这不会适用)。


但是,验证什么呢?
6

请详细说明,@ nephewtom。您想澄清什么?
yuranos

我阅读了《 JSR 303:Bean验证》,beanvalidation.org / 1.0 / spec, 但仍然没有得到对的验证ScriptFile scriptFile
nephewtom

其中的ScriptFile可能有很多字段,这些字段也都带有注释。这就是验证的起点。基于最初的问题,尚不清楚ScriptFile类内部到底是什么。
yuranos

好,谢谢。您能否举一个可以验证其字段是否为字符串,整数和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

只是添加到上面的答案中,在Web应用程序 @valid中,在要验证的bean上也使用验证注释(例如@NotNull@Email(休眠注释))进行注释,因此当从用户获取输入时,可以验证值,并且绑定结果将具有验证结果。 bindingResult.hasErrors()会告诉您验证是否失败。


1

上面没有提到的@Valid的另一个方便方面是(例如:使用Postman测试端点)@Valid将不正确的REST调用的输出格式化为格式化的JSON,而不是难以读取的文本。如果您要为用户创建可商业使用的API,这将非常有用。


0

我想我知道你的问题要去哪里。而且由于这个问题是在Google搜索的主要结果中弹出的,所以我可以就@Valid注释的作用给出一个简单的答案。

我将介绍有关如何使用@Valid的3种情况

模型:

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等)的验证,您仍然需要指定执行策略验证结果。

希望我能够为可能会为此迷惑的人们清除一些东西。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.