下面我来详细讲解一下“springboot 传参校验@Valid及对其的异常捕获方式”的完整攻略。
1. 什么是@Valid注解
Spring Boot 在处理 Web 请求时,通常会使用数据绑定将请求中的数据映射到 Controller 中的方法参数列表里。当数据格式不正确或缺失时,我们往往会在方法中手动校验数据,这会增加开发的耗时,也容易产生错误。而@Valid注解就可以在数据绑定之后自动进行数据校验。
2. 如何使用@Valid注解
要在 Spring Boot 中使用@Valid注解,我们需要先添加以下依赖:
<!-- Spring Boot Web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Hibernate Validator 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
首先在 Controller 类中的要校验的参数前面加上@Valid注解:
@RequestMapping("/addUser")
public String addUser(@Valid User user, BindingResult bindingResult) {
// ...
}
然后在 User 类中定义我们需要进行的校验规则:
public class User {
@NotBlank(message = "姓名不能为空")
@Size(min = 2, max = 4, message = "姓名长度必须是2-4个字符")
private String name;
@NotNull(message = "年龄不能为空")
@Min(value = 18, message = "年龄必须大于等于18岁")
@Max(value = 60, message = "年龄必须小于等于60岁")
private Integer age;
// ...getter/setter方法省略
}
以上就是@Valid注解的使用方式。
3. 对@Valid校验异常的捕获方式
虽然@Valid注解提供了便利,但当校验失败时,没有对应的异常被抛出,我们需要手动处理校验失败的情况。处理校验失败时,我们可以使用BindingResult对象来获取具体的校验失败信息。
我们可以在 Controller 方法中声明一个BindingResult参数,当校验失败时,方法会被调用,且BindingResult对象会被自动填充。
@RequestMapping("/addUser")
public String addUser(@Valid User user, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
StringBuffer errorMsgs = new StringBuffer();
for (ObjectError error : bindingResult.getAllErrors()) {
errorMsgs.append(error.getDefaultMessage()).append(",");
}
// 返回给前端处理异常信息
return errorMsgs.toString();
}
// 业务处理
return "success";
}
以上是手动处理校验异常的方式。
4. 示例说明
下面我们给出两个示例来说明@Valid注解的使用。
4.1 示例一
我们要添加一个用户到数据库中,如果用户的姓名为空或超出长度范围,或者年龄超出合法范围,则不能添加用户。以下是Controller代码:
@RestController
@RequestMapping("/test")
public class UserController {
@Autowired
private UserService userService;
/**
* 添加用户
* @param user 用户实体类
* @param bindingResult 数据校验结果
* @return 处理结果
*/
@PostMapping("/user")
public Result addUser(@Valid User user, BindingResult bindingResult) {
// 校验失败,返回错误信息
if (bindingResult.hasErrors()) {
List<ObjectError> allErrors = bindingResult.getAllErrors();
StringBuilder errorMsg = new StringBuilder("数据校验失败:");
for (ObjectError objectError : allErrors) {
errorMsg.append(objectError.getDefaultMessage()).append(";");
}
return Result.fail(errorMsg.toString(), null);
}
// 调用Service处理业务
boolean result = userService.addUser(user);
if (result) {
return Result.success("添加用户成功!", null);
}
return Result.fail("添加用户失败!", null);
}
}
在User类中,我们添加一些数据校验规则,如下:
@Data
public class User {
@NotBlank(message = "姓名不能为空")
@Size(min = 2, max = 5, message = "姓名长度必须为2-5个字符")
private String name;
@NotNull(message = "年龄不能为空")
@Max(value = 120, message = "年龄不能超过120岁")
@Min(value = 0, message = "年龄不能小于0岁")
private Integer age;
private String address;
private String mobileNo;
}
4.2 示例二
我们需要校验用户输入的手机号是否合法,如果不合法,则返回错误信息。以下是Controller代码:
@RestController
@RequestMapping("/test")
public class UserController {
/**
* 用户注册
* @param mobileNo 手机号
* @param bindingResult 校验结果
* @return 校验结果
*/
@GetMapping("/register")
public Result register(@RequestParam("mobileNo") @Pattern(regexp = "1\\d{10}", message = "手机号格式错误") String mobileNo,
BindingResult bindingResult) {
// 校验失败,返回错误信息
if (bindingResult.hasErrors()) {
List<ObjectError> allErrors = bindingResult.getAllErrors();
StringBuilder errorMsg = new StringBuilder("数据校验失败:");
for (ObjectError objectError : allErrors) {
errorMsg.append(objectError.getDefaultMessage()).append(";");
}
return Result.fail(errorMsg.toString(), null);
}
// 调用Service处理业务
boolean result = userService.register(mobileNo);
if (result) {
return Result.success("用户注册成功!", null);
}
return Result.fail("用户注册失败!", null);
}
}
在@RequestParam注解上加上@Pattern注解来校验手机号是否合法。如果手机号不合法,则会抛出MethodArgumentNotValidException异常,我们需要进行处理,如下:
/**
* 捕获校验失败的异常,返回错误信息
* @param ex 异常信息
* @return 错误信息
*/
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 捕获校验失败的异常,返回错误信息
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
BindingResult bindingResult = ex.getBindingResult();
List<ObjectError> allErrors = bindingResult.getAllErrors();
StringBuilder errorMsg = new StringBuilder("参数校验失败:");
for (ObjectError objectError : allErrors) {
errorMsg.append(objectError.getDefaultMessage()).append(";");
}
return Result.fail(errorMsg.toString(), null);
}
}
以上就是两个示例,通过这种方式可以大大减少代码量,提高开发效率。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot 传参校验@Valid及对其的异常捕获方式 - Python技术站