1.背景
一个健壮的系统都要对外部提交的数据进行完整性、合法性的校验。
校验是我们程序开发中必不可少的过程。
即使开发一个不面对最终用户的工具包,也需要对传入的数据进行缜密的校验来防止引发底层难以追踪的问题。
后端参数校验最简单的做法是直接在业务方法里面进行判断,当判断成功之后再继续往下执行。但这样带给我们的是代码的耦合,冗余。当我们多个地方需要校验时,我们就需要在每一个地方调用校验程序,导致代码很冗余,且不美观。
2.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
3.添加配置
package com.bylz.framework.validation;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
/**
* springboot validation
* 校验参数配置
*/
@Configuration
public class WebConfig {
@Bean
public Validator validator() {
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
//failFast为true出现校验失败的情况,立即结束校验,不再进行后续的校验
.failFast(true)
.buildValidatorFactory();
return validatorFactory.getValidator();
}
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
methodValidationPostProcessor.setValidator(validator());
return methodValidationPostProcessor;
}
}
4.配置全局异常处理
package com.bylz.common.exception;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
/**
* Author: lizhi
* Date: 2021-08-27
* Describe: 全局异常捕获
*/
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
* 处理参数校验异常
* @param e
* @return ResponseData
*/
@ExceptionHandler(BindException.class)
@ResponseBody
public String bindExceptionHandler(BindException e) {
log.error("参数错误bind:{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
return e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
}
/**
* 处理参数校验异常
* @param e
* @return ResponseData
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public String methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
log.error("参数错误not valid:{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
return e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
}
}
5.接口参数校验
接口注解@Valid:
/**
* 用户登录
* @param loginDto
* @return ResponseData
*/
@PostMapping("/login")
public ResponseData login(@RequestBody @Valid LoginDto loginDto) {
return ResponseData.success(CommonEnum.SUCCESS.getResultCode(), CommonEnum.SUCCESS.getResultMsg(), sysLoginService.login(loginDto));
}
DTO校验注解使用:
package com.bylz.qcloudauth.entity.dto;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* 登录参数实体类
*/
@Data
public class LoginDto implements Serializable {
private static final long serialVersionUID = 8800506466012829191L;
@NotBlank(message = "用户名不能为空")
@Length(max = 6, message = "用户名超长")
private String username;
@NotBlank(message = "密码不能为空")
@Length(min = 6, max = 20, message = "密码在6-20位之间")
private String password;
}
备注:相关更多校验字段注解使用,请查看官网使用或者阅读其他博客,在此只做集成介绍!!
6.postman测试