在以下示例中,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();
}
答案 0 :(得分:49)
用于验证目的。
验证通常验证a 绑定用户输入后的模型。 Spring 3提供支持 使用JSR-303进行声明性验证。 此支持自动启用 如果是JSR-303提供者,比如 Hibernate Validator存在于 你的类路径。启用后,您可以 简单地触发验证 注释Controller方法 带@Valid注释的参数: 绑定传入POST后 参数,AppointmentForm会 得到验证;在这种情况下,要验证 日期字段值不为null 发生在将来。
在这里查看更多信息:
http://blog.springsource.com/2009/11/17/spring-3-type-conversion-and-validation/
答案 1 :(得分:23)
添加以上答案,请看下面的内容。 AppointmentForm
' date
列标注了几个注释。通过@Valid
注释触发AppointmentForm
上的验证(在本例中为@NotNull
和@Future
)。这些注释可能来自不同的JSR-303提供程序(例如,Hibernate,Spring ..等)。
@RequestMapping(value = "/appointments", method = RequestMethod.POST)
public String add(@Valid AppointmentForm form, BindingResult result) {
....
}
static class AppointmentForm {
@NotNull @Future
private Date date;
}
答案 2 :(得分:14)
IIRC @Valid不是Spring注释,而是JSR-303注释(这是Bean Validation标准)。它的作用是基本检查您发送给方法的数据是否有效(它将为您验证scriptFile)。
答案 3 :(得分:11)
@Valid
本身与Spring无关。它是Bean Validation规范的一部分(其中有几个,最新的一个是JSR 380,截至2017年下半年),但是@Valid
非常老,并且从JSR 303一直派生。 / p>
众所周知,Spring非常擅长提供与所有不同的JSR和Java库的集成(想想JPA,JTA,Caching等),当然这些人也负责验证。促进这一点的关键组成部分之一是MethodValidationPostProcessor。
尝试回答您的问题 - 当您想要验证复杂图形而不仅仅是对象的顶级元素时,@Valid
对于所谓的验证级联非常方便。每次想要更深入时,都必须使用@Valid
。这就是JSR所要求的。 Spring会遵循一些小的偏差(例如我尝试将@Validated
而不是@Valid
放在RestController方法和验证工作上,但同样不适用于常规"服务&#34 ;豆)。
答案 4 :(得分:2)
public String create(@Valid @NotNull ScriptFile scriptFile, BindingResult result, ModelMap modelMap) {
if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");
我想这个@NotNull
注释是有效的,因此如果不需要条件。
答案 5 :(得分:1)
只需添加上述答案,即可在网络应用程序中使用
@valid
用于要验证的bean也使用验证注释注释的地方,例如@NotNull
,@Email
(hibernate注释)因此,当从用户获取输入时,可以验证值,并且绑定结果将具有验证结果。
bindingResult.hasErrors()
将告知任何验证是否失败。
答案 6 :(得分:1)
我想我知道你的问题要去哪里。而且由于这个问题是在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字段的表单后,您将得到一个错误页面,因为您正在应用验证规则,但未对其进行任何处理。
上述错误的示例: Exception page
方案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
}
在这种情况下,您仍然没有像在第一种情况下那样处理错误,但是将其传递给另一种方法,该方法将处理在处理表单模型时<strong> @Valid 触发的异常。检查this,了解如何处理映射以及所有这些操作。
总结:@Valid本身不会执行触发验证JSR 303注释字段( @ NotNull,@ Email,@ Size等的验证)的操作。 ),您仍然需要指定一种处理验证结果的策略。
希望我能够为可能会为此迷失方向的人们清除一些东西。
答案 7 :(得分:0)
@Valid的另一个方便的方面是上面没有提到的(即:使用Postman测试端点),@ Valid会将不正确的REST调用的输出格式化为格式化的JSON,而不是难以读懂的文本。如果您要为用户创建可商业使用的API,这将非常有用。
答案 8 :(得分:0)
我想添加更多有关@Valid
工作原理的详细信息,尤其是在春季。
https://reflectoring.io/bean-validation-with-spring-boot/中清楚,详细地介绍了您想知道的有关春季验证的所有信息,但是如果链接断开,我将复制@Valid
的工作原理。
可以将@Valid
批注添加到rest控制器方法中的变量以对其进行验证。可以验证3种类型的变量:
那么现在...弹簧如何“验证”?您可以通过使用某些注释来对类的字段定义约束。然后,将该类的对象传递到Validator中,该Validator检查是否满足约束条件。
例如,假设我有这样的控制器方法:
@RestController
class ValidateRequestBodyController {
@PostMapping("/validateBody")
ResponseEntity<String> validateBody(@Valid @RequestBody Input input) {
return ResponseEntity.ok("valid");
}
}
这是一个包含响应主体的POST请求,我们正在将该响应主体映射到类Input
。
这是课程Input
:
class Input {
@Min(1)
@Max(10)
private int numberBetweenOneAndTen;
@Pattern(regexp = "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$")
private String ipAddress;
// ...
}
@Valid注释将通过检查是否由于最小和最大注释而检查整数numberBetweenOneAndTen
是否在1到10之间(包括10和10),从而告诉spring去验证传递到控制器中的数据。它还将检查以确保传入的IP地址与注释中的正则表达式匹配。
旁注:正则表达式不是完美的..您可以传入大于255的3位数字,但它仍然与正则表达式匹配。
下面是验证查询变量和路径变量的示例:
@RestController
@Validated
class ValidateParametersController {
@GetMapping("/validatePathVariable/{id}")
ResponseEntity<String> validatePathVariable(
@PathVariable("id") @Min(5) int id) {
return ResponseEntity.ok("valid");
}
@GetMapping("/validateRequestParameter")
ResponseEntity<String> validateRequestParameter(
@RequestParam("param") @Min(5) int param) {
return ResponseEntity.ok("valid");
}
}
在这种情况下,由于查询变量和路径变量只是整数而不是复杂的类,因此我们将约束注释@Min(5)
放在参数上,而不是使用@Valid
。