1. 程式人生 > 實用技巧 >springboot @valid與@validated的引數校驗使用總結

springboot @valid與@validated的引數校驗使用總結

好久沒在這平臺寫部落格了,最近整理了這東西,先給出總結

//  @Valid只能用在controller,@Validated可以用在其他被spring管理的類上
//  @Valid可以加在成員變數上(本人一般只有在巢狀查詢的時候才會使用這個註解)
//  @Validated可以分組
//  @Valid可以加在成員變數上,所以可以巢狀校驗
以及我在總結時隨便寫的類(東西都在程式碼裡,(*^▽^*))
@RestController
@RequestMapping("/check")
@Validated
public class ParamCheckInController {

    @Autowired
    
private ParamCheckInService paramCheckInService; @PostMapping("/postDemo") public Node postDemo(@RequestBody @Validated Node node) { return node; } @GetMapping("/getDemo") public Node getDemo(@Validated Node node) { paramCheckInService.test("a","b"); return
node; } @GetMapping("/getDemo2") public String getDemo2( @NotEmpty String s) { return s; } @PostMapping("/groupDemo1") public Book groupDemo1(@RequestBody @Validated Book book) { return book; } @PostMapping("/groupDemo2") public Book groupDemo2(@RequestBody @Validated({InsertGroup.class
,}) Book book) { return book; } @PostMapping("/groupDemo3") public Node groupDemo3(@RequestBody @Validated({InsertGroup.class,UpdateGroup.class}) Node node) {//還有啥@Validated分組是有序校驗的之類,感覺沒啥用 return node; } } @Data class Node implements Serializable { @NotBlank(message = "名稱不能為空") private String name; @NotEmpty(groups = UpdateGroup.class,message = "性別不能為空") private String sex; @NotNull(groups =InsertGroup.class,message = "年齡不能為空") @Max(value = 200,message = "age不能大於200") private Integer age; @Valid //對下層進行巢狀呼叫 @NotEmpty(message = "bookList不能為空") private List<Book> bookList; } @Data class Book implements Serializable{ @NotEmpty(groups = {UpdateGroup.class, Default.class}, message = "更新時id不能為空") private String id; @NotNull(groups = {InsertGroup.class}, message = "新增時bookName不能為空") private String bookName; }
@Service
@Slf4j
@Validated
public class ParamCheckInService {
    public @NotNull(message = "返回值不允許為空") String test(@NotEmpty(message = "s不能為空") String s,String b){
        return b;
    }
}

上面的類是本人在總結知識點時自己測試的,而且因為要返回給前端,所以還要全域性異常捕獲,或者在每個方法用BindResult接收。

@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({MethodArgumentNotValidException.
class,BindException.class}) @ResponseStatus(HttpStatus.OK) @ResponseBody public Result<T> handleMethodArgumentNotValidException(Exception exception) { StringBuilder errorInfo = new StringBuilder(); BindingResult bindingResult=null; if(exception instanceof MethodArgumentNotValidException){ bindingResult= ((MethodArgumentNotValidException)exception).getBindingResult(); } if(exception instanceof BindException){ bindingResult= ((BindException)exception).getBindingResult(); } for(int i = 0; i < bindingResult.getFieldErrors().size(); i++){ if(i > 0){ errorInfo.append(","); } FieldError fieldError = bindingResult.getFieldErrors().get(i); errorInfo.append(fieldError.getField()).append(" :").append(fieldError.getDefaultMessage()); } return Result.error(errorInfo.toString()); } @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public Result<T> handleDefaultException(Exception exception) { return Result.error("其他錯誤"); } }

還有需要注意的一點是在分組時,介面如果不繼承Default的話,有分組校驗的介面是必須加上Default.class的否則會使一些校驗註解無效

所以我會在分組的介面上繼承Default,不然需要分組的引數都要加Default.class看著不舒服~(controller看著簡潔就行,嘿嘿~)

public interface UpdateGroup extends Default {
}
public interface InsertGroup extends Default {
}