在Spring中,校验表单数据是十分常见的一个需求。Spring提供了Validator接口来进行校验。在本篇攻略中,我将为你详细讲解如何使用Spring Validator接口进行数据校验,并结合全局异常处理器对校验结果进行处理。
1. Spring Validator接口
Spring Validator接口是一个用于校验数据的接口,可以通过实现该接口来编写自定义的数据校验器。
1.1 实现Validator接口
创建一个数据校验器,需要实现Validator接口,并重写该接口中的两个方法:supports()和validate()。
-
supports():验证该校验器是否能校验指定的数据类型。如果该校验器支持校验该数据类型,则返回true,否则返回false。
-
validate():实现具体的校验逻辑。如果校验失败,则需要通过抛出异常的方式来提示错误消息。
例如,下面是一个简单的数据校验器示例:
public class UserValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return User.class.equals(clazz); // 仅支持User类型的数据校验
}
@Override
public void validate(Object target, Errors errors) {
User user = (User) target;
if (user.getUsername() == null || user.getUsername().isEmpty()) {
errors.rejectValue("username", "notEmpty", "用户名不能为空");
}
if (user.getPassword() == null || user.getPassword().isEmpty()) {
errors.rejectValue("password", "notEmpty", "密码不能为空");
}
}
}
在上面的例子中,我们实现了一个用于校验User对象的数据校验器。其supports()方法仅支持User类型的数据校验;而validate()方法则校验了User对象的username和password字段是否为空,如果为空,则将校验结果加入到Errors对象中。
1.2 使用校验器
当我们创建好了一个数据校验器后,就可以使用它来对数据进行校验了。Spring提供了一个Valid注解,可以将该注解标注在方法参数上,表示使用该方法参数的校验器来校验该参数数据。
例如,下面是一个Controller中的例子:
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity<Object> addUser(@Valid @RequestBody User user) {
userService.addUser(user);
return ResponseEntity.ok().build();
}
// ...
}
在上面的例子中,我们使用Valid注解来对User对象进行校验。如果校验失败,则Spring会自动抛出MethodArgumentNotValidException异常,然后我们需要在全局异常处理器中对该异常进行处理。
2. 全局异常处理器
全局异常处理器是一种Spring提供的机制,它可以统一处理控制器抛出的异常。通常情况下,我们可以通过@ControllerAdvice注解来实现全局异常处理器。
2.1 实现全局异常处理器
全局异常处理器一般需要实现ExceptionHandler接口,并结合@ControllerAdvice注解来进行使用。ExceptionHandler接口中需要实现的方法是对具体异常的处理逻辑,例如,下面是一个处理MethodArgumentNotValidException异常的全局异常处理器示例:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
BindingResult bindingResult = ex.getBindingResult();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
String errorMsg = "参数错误:";
for (FieldError fieldError : fieldErrors) {
errorMsg += fieldError.getDefaultMessage() + "; ";
}
return ResponseEntity.badRequest().body(errorMsg);
}
// ...
}
在上面的例子中,我们通过ExceptionHandler注解来声明了对MethodArgumentNotValidException异常的处理方式。具体的处理逻辑是从BindingResult对象中获取FieldError列表,将错误提示信息合并后返回给用户。
2.2 使用全局异常处理器
当我们实现了一个全局异常处理器后,就需要将它注册到Spring中,以供后续使用。常见的方式是使用@Bean注解将该异常处理器注册到Spring上下文中。
例如,下面是一个注册全局异常处理器的配置类示例:
@Configuration
public class GlobalExceptionHandlerConfig {
@Bean
public GlobalExceptionHandler globalExceptionHandler() {
return new GlobalExceptionHandler();
}
// ...
}
在上面的例子中,我们将GlobalExceptionHandler类注册为一个Spring Bean,以供后续使用。
3. 完整示例
下面是一个完整的示例,包括一个User对象、一个UserValidator校验器和一个全局异常处理器。该示例将演示如何使用getData()方法获取用户数据,并对其进行校验和处理异常。
public class User {
private String username;
private String password;
// getter/setter
}
public class UserValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return User.class.equals(clazz); // 仅支持User类型的数据校验
}
@Override
public void validate(Object target, Errors errors) {
User user = (User) target;
if (user.getUsername() == null || user.getUsername().isEmpty()) {
errors.rejectValue("username", "notEmpty", "用户名不能为空");
}
if (user.getPassword() == null || user.getPassword().isEmpty()) {
errors.rejectValue("password", "notEmpty", "密码不能为空");
}
}
}
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
BindingResult bindingResult = ex.getBindingResult();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
String errorMsg = "参数错误:";
for (FieldError fieldError : fieldErrors) {
errorMsg += fieldError.getDefaultMessage() + "; ";
}
return ResponseEntity.badRequest().body(errorMsg);
}
// ...
}
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity<Object> addUser(@RequestBody User user) {
UserValidator validator = new UserValidator();
validator.validate(user, new BeanPropertyBindingResult(user, "user"));
userService.addUser(user);
return ResponseEntity.ok().build();
}
// ...
}
@Configuration
public class GlobalExceptionHandlerConfig {
@Bean
public GlobalExceptionHandler globalExceptionHandler() {
return new GlobalExceptionHandler();
}
// ...
}
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
在该示例中,我们使用UserValidator校验器对User对象进行校验,并使用全局异常处理器对校验失败的情况进行了统一处理。注意在UserController中,我们手动创建了一个UserValidator实例,并使用它对User对象进行了校验的调用。当校验失败时,会抛出MethodArgumentNotValidException异常,并由全局异常处理器统一处理。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Validator接口校验与全局异常处理器 - Python技术站