dto参数校验及统一异常处理

本文详细介绍了SpringBoot中使用@Valid和@Validated注解进行数据校验的方法,包括分组校验、嵌套校验以及如何设置自定义分组。同时,还探讨了如何通过@ControllerAdvice和@ExceptionHandler处理全局异常,特别是BindException的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总结

@Valid 和 @Validated 比较
(1)@Valid 和 @Validated 两者都可以对数据进行校验,待校验字段上打的规则注解(@NotNull, @NotEmpty等)都可以对 @Valid 和 @Validated 生效;
(2)@Valid 进行校验的时候,需要用 BindingResult 来做一个校验结果接收。当校验不通过的时候,如果手动不 return ,则并不会阻止程序的执行;
(3)@Validated 进行校验的时候,当校验不通过的时候,程序会抛出400异常,阻止方法中的代码执行,需要写一个全局校验异常捕获处理类,然后返回校验提示。
(4)总体来说,@Validated 使用起来要比 @Valid 方便一些。

大部分参考以下链接

@Valid 和 @Validated 注解用法详解

本地实践

分组校验@Validated(Group1.class) ValidDTO validDTO

@Controller
@RequestMapping(value = "/valid")
public class ValidController {

  @RequestMapping(value = "/update")
  @ResponseBody
  //分组
  public Result<Object> update(@RequestBody @Validated(Group1.class) ValidDTO validDTO) {
    System.out.println(validDTO.getHobbyList());
    return Result.success(validDTO.getName() +"," +validDTO.getId());
  }

  @RequestMapping(value = "/insert")
  @ResponseBody
  public Result<Object> insert(@RequestBody @Validated(Default.class) ValidDTO validDTO) {
    System.out.println(validDTO.getHobbyList());
    return Result.success(validDTO.getName() +"," +validDTO.getId());
  }
}

嵌套校验时需要给自定义类加@Valid注解

@Data
public class ValidDTO {
    //分组,可以区分insert和update时是否需要id
    @NotNull(message = "修改时id不为空", groups = Group1.class)
    private Integer id;
    @NotBlank(message = "请输入姓名")
    private String name;
    @Size(message = "兴趣最多{max}", max = 5)
    private List<String> hobbyList;
    @Valid
    private UserDTO userDTO;
}
@Data
public class UserDTO {
    @NotBlank(message = "UserDTO修改时id不为空")
    private String id;
    @NotBlank(message = "UserDTO请输入姓名")
    private String name;
}

分组时需要继承Default默认分组,因为当不加分组时默认分组为Default,
如果不继承Default,自定义分组Group1只对加了这个分组的字段生效

public interface Group1 extends Default {
}

全局异常处理
处理BindException,将参数校验的第一条异常信息返回给前端
@ControllerAdvice注解:通过在类上添加 @ControllerAdvice 注解,可以让这个类成为一个全局异常处理类,用来捕获在 Controller 层抛出的异常。
@ExceptionHandler注解的方法,用于处理特定类型的异常

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    protected static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler({Exception.class})
    @ResponseBody
    public Result<CodeMsg> handleException(Exception e){
        if ((e instanceof ClientAbortException)) {
            return null;
        } else {
            e.printStackTrace();
            if (e instanceof InvalidFormatException || e instanceof HttpMessageNotReadableException) {
                return Result.MethodArgumentNotValidException;
            } else if (e instanceof MissingServletRequestParameterException){
                return Result.MissingRequestParameter;
            }else if(e instanceof HttpRequestMethodNotSupportedException){
                return Result.RequestMethodNotSupported;
            }
            else if(e instanceof BindException){
                BindException exception = (BindException) e;
                CodeMsg codeMsg = new CodeMsg(-400, exception.getAllErrors().get(0).getDefaultMessage());
                return Result.error(codeMsg);
            }
            return Result.SERVER_ERROR;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值