Spring Boot validation 参数校验 List

1,872 阅读1分钟

简介

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 了

转载需注明出处,抄袭必究