简介
Web 应用前端访问后端传入参数,需要做参数校验,以往都是在 service 层做校验,或者封装到参数类中,作为类的行为方法,这里介绍的是另外一种注解方式。参数传递分为几种方式,通过对象传递(Post、Putq请求使用表单)、直接使用具体参数名称传递(Get请求使用@RequestParam注解)、或者集合传递(List、set)。前面两种比较简单,这里用 List 示例
引用
Spring boot 版本在 2.3.X 以前的直接被 spring-boot-starter-web 引用进来,2.3.X 以后的版本要单独引入
Gradle
implementation 'org.springframework.boot:spring-boot-starter-validation'
或者
implementation 'org.hibernate.validator:hibernate-validator:8.0.0.Final'
使用
Controller 中在具体请求方法上增加 @Validated 注解,这里需要注意加在 @ResquestBody 注解后面,而不是前面
@PostMapping("/test")
@ResponseStatus(HttpStatus.CREATED)
@Validated
private void test(@RequestBody @Validated ValidationList<TestDTO> testDTO) {
testDao.test(testDTO);
}
集合参数类型需要自定义参数类型,这里我们定义了 ValidationList 用来接收参数,一定要重写 toString 方法,其他方法可以使用 @Delegate 注解
import lombok.experimental.Delegate;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
public class ValidationList<E> implements List<E> {
@Delegate
@Valid
public List<E> list = new ArrayList<>();
@Override
public String toString() {
return list.toString();
}
}
参数对象中我们就可以直接使用校验注解来判断参数非空、长度、格式等操作
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TestDTO {
@NotBlank(message="id must not blank")
private String id;
...
}
如果参数验证不通过,会直接提示系统异常,我们如果需要把 message 中的信息抛出,我们需要增加统一的异常处理
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.DataBinder;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.net.BindException;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
// 这里是必须要增加的
@InitBinder
private void activateDirectFieldAccess(DataBinder dataBinder) {
dataBinder.initDirectFieldAccess();
}
// 这里用来接收参数验证抛出的异常,并打印 message 信息抛出给
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity throwCustomException(MethodArgumentNotValidException e){
log.error(e.getMessage());
HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
ErrorResult errorResult = new ErrorResult(e.getBindingResult().getFieldError().getDefaultMessage());
return new ResponseEntity<>(errorResult, httpStatus);
}
}
到此我们就可以正常校验 List 参数中的属性,并抛出自定义的 message 了
转载需注明出处,抄袭必究