Spring Boot应用程序使用@valid来验证API请求
使用@valid可以使你的Request验证更容易。
当我们开发rest API时,我们认为每个人都需要验证接口输入参数的合法性。
一些初学者可能会使用许多if-else条件表达式进行验证。以一个新的用户注册为例。
@RestController
public class DemoController {
@PostMapping("/user/register")
public Boolean registerUser(@RequestBody UserRegisterRequest request) {
if (StringUtils.isBlank(request.getName() == null)) {
throw new IllegalArgumentException("username is required");
}
if (StringUtils.isBlank(request.getpassword())) {
throw new IllegalArgumentException("password is required");
}
if (StringUtils.isBlank(request.getEmail())) {
throw new IllegalArgumentException("email is required");
}
..........
}
}
这样的代码可以达到参数验证的目的,但是细心的读者可能已经发现,如果我们想写很多这样的接口,就需要重复写很多验证代码,这显然不优雅。
我们可以使用@valid注解来帮助我们简化验证逻辑。
使用@Valid
hibernate-validator实现了@Valid。spring-boot-start-web已经包含这个库,所以不需要引入依赖关系。如果是非spring项目,需要使用两个Maven依赖项。
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.14.Final</version>
</dependency>
以下是与@valid相关的注解。在实体类的属性中添加不同的注解可以实现验证功能。
- @Null限制属性只能为空。
- @NotNull限制属性不能为空。
- @Max(value) 限制属性必须是一个不大于指定值的数字。
- @Min(value)限制属性必须是一个不小于指定值的数字。
- @Digits(integer, fraction) 限制属性必须是一个小数,而且整数部分的数字不能超过整数,小数部分的数字不能超过分数。
- @过去限制属性必须是一个过去的日期。
- @Future 限制属性必须是一个未来的日期。
- @Pattern(value) 限制属性必须符合指定的正则表达式。
- @Size(max, min) 限制字符长度必须在min和Max之间。
- @NotEmpty有效属性值不能为空,字符串长度不能为0,集合大小不能为0。
- @NotBlank 有效的属性值不是空的,并且在trim()之后,长度不是0。
- @Email 验证属性值是一个电子邮件格式的字符串。
使用@valid注解来完成参数验证是非常简单的。你只需要在实体类的属性中添加适当的注解。
上面是同一个新用户注册的例子。
public class UserRegisterRequest {
@Pattern(regexp = "1[3-9]{1}[0-9]{9}", message = "the user phone is illegal.")
private String phone;
@Email
private String email;
@NotBlank(message = "username is required.")
@Size(min = 1, max = 225, message = "username is too long.")
private String username;
@NotBlank(message = "password is required.")
@Min(value = 8, message = "The new password is too short.")
private String password;
//If entity nesting exists, @valid annotation must be added
@Valid
@NotNull
private Address address;
.....
}
public class Address {
@NotBlank
private String provice;
@NotBlank
private String city;
@NotBlank
private String detailAddress;
}
@RestController
public class DemoController {
@PostMapping("/user/register")
public Boolean registerUser(@Valid @RequestBody UserRegisterRequest request) {
}
看,就是这么简单。一些注释完成了复杂的验证逻辑。当对目标参数的验证失败时,系统会抛出一个MethodArgumentNotValidException异常。
然后,我们可以使用@ExceptionHandler来处理验证结果。
使用@Exceptionhandler来统一处理验证结果
public class ErrorResult implements Serializable {
private long code;
private String msg;
public long getCode() {
return code;
}
public void setCode(long code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
@Component
public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public ErrorResult parameterExceptionHandler(MethodArgumentNotValidException e) {
BindingResult exceptions = e.getBindingResult();
if (exceptions.hasErrors()) {
List<ObjectError> errors = exceptions.getAllErrors();
if (!errors.isEmpty()) {
FieldError fieldError = (FieldError) errors.get(0);
return new ErrorResult(-1,fieldError.getDefaultMessage());
}
}
return new ErrorResult(-1,"argument valid failure");
}
这里创建了一个全局异常处理类。我们使用parameterExceptionHandler方法来捕捉MethodArgumentNotValidException异常,最后,统一处理验证失败的结果。
这个方法将在每个字段的验证失败后得到错误信息。
这里,我使用ErrorResult类来返回错误信息。当我们启动服务时,我们使用postman来发起一个post请求(http://localhost:8080/user/register ),我们不输入任何参数并返回结果。
{
"code": -1,
"msg": "the user phone is illegal."
}
本文简要介绍了在spring boot中使用@valid来验证API请求。我希望这篇文章能够帮助你。谢谢你的阅读。