zoukankan      html  css  js  c++  java
  • @Valid 数据校验 + 自定义全局异常信息

    关于javax.validation.Validator校验的使用

    • 对于要校验的实体类:其需要校验的字段上需要添加注解

    常用注解

    实际例子

    实体类Demo

    使用:首先要拿到 validator的子类

    Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    其中方法可以参考 API
    对实体类的校验

    Set<ConstraintViolation<Object>> set = validator.validate(obj,Default.class);
     

    本文链接:https://blog.csdn.net/qq_38193966/article/details/95990268

    ———————————————— 

    @Valid 数据校验 + 自定义全局异常信息

    我们常用@Valid做数据校验,比如现在前端要新增一个用户,我们可以这样校验:

    @RestController
    public class UserController {
    
        @PostMapping("/user")
        public void addUser(@RequestBody @Valid RequestDTO requestDTO){
            //其余业务处理
            System.out.println(requestDTO.toString());
        }
    }
    

    传入的数据规则如下列代码所示:

    
    @Data
    public class RequestDTO {
        @NotNull(message = "名字不能为空")
        String name;
    
        @NotEmpty(message = "密码不能为空")
        String password;
    
        @Override
        public String toString() {
            return "name=" + name + ",password=" + password;
        }
    }
    
    

    假设我们模仿前端伪造了一个非法数据(例如密码为空):

    {
      "name": "string",
      "password": ""
    }
    

    加了@Valid注解的程序就能按我们的预期报错:

    {
      "timestamp": "2019-08-26T14:12:02.542+0000",
      "status": 400,
      "error": "Bad Request",
      "errors": [
        {
          "codes": [
            "NotEmpty.requestDTO.password",
            "NotEmpty.password",
            "NotEmpty.java.lang.String",
            "NotEmpty"
          ],
          "arguments": [
            {
              "codes": [
                "requestDTO.password",
                "password"
              ],
              "arguments": null,
              "defaultMessage": "password",
              "code": "password"
            }
          ],
          "defaultMessage": "密码不能为空",
          "objectName": "requestDTO",
          "field": "password",
          "rejectedValue": "",
          "bindingFailure": false,
          "code": "NotEmpty"
        }
      ],
      "message": "Validation failed for object='requestDTO'. Error count: 1",
      "path": "/user"
    }
    

    报错信息改进

    但这样的报错信息明显太冗余了,我们想简化下,只抛出有问题字段的报错信息,这回就可以结合我们的全局异常进行处理:

    1.编写自定义异常处理类,绑定要处理的异常

    这里我们注意到@Valid抛出的异常类是MethodArgumentNotValidException ,所以我们将捕获该异常,并对它重新自定义异常信息

    @ControllerAdvice
    public class GlobalExceptionHandler {
        @ExceptionHandler(value = MethodArgumentNotValidException.class)
        @ResponseBody
        public JsonResult MyExceptionHandle(MethodArgumentNotValidException exception){
            exception.printStackTrace();
            BindingResult result = exception.getBindingResult();
            StringBuilder errorMsg = new StringBuilder() ;
            
            if (result.hasErrors()) {
                List<FieldError> fieldErrors = result.getFieldErrors();
                fieldErrors.forEach(error -> {
                    System.out.println("field" + error.getField() + ", msg:" + error.getDefaultMessage());
                    errorMsg.append(error.getDefaultMessage()).append("!");
                });
            } 
    
            exception.printStackTrace();
            return new JsonResult(-1,errorMsg.toString() );
        }
    }
    
    

    上面的代码就是取出里面的报错信息,组装成自己需要显示的信息(这里我们封装成一个json结构,包括状态码和信息返出去):

    1. 试验成果

    将刚刚的请求再发一遍,现在就可以看到,错误信息已经按照我们规定的格式返回了:

    {
      "code": -1,
      "msg": "密码不能为空!"
    }
  • 相关阅读:
    Windows Server 2012配置开机启动项
    Windows Server 2019 SSH Server
    NOIP2017 senior A 模拟赛 7.7 T1 棋盘
    Noip 2015 senior 复赛 Day2 子串
    Noip 2015 senior复赛 题解
    Noip 2014 senior Day2 解方程(equation)
    Noip 2014 senior Day2 寻找道路(road)
    Noip 2014 senior Day2 无线网络发射器选址(wireless)
    Noip2014senior复赛 飞扬的小鸟
    Noip 2014 senior 复赛 联合权值(link)
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/11994742.html
Copyright © 2011-2022 走看看