• @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": "密码不能为空!"
    }
  • 相关阅读:
    Redis5设计与源码分析 (第17章 HyperLogLog相关命令的实现)
    Redis5设计与源码分析 (第16章 GEO相关命令)
    ES5和ES6函数的this指向
    vue响应式原理 (响应式并不等于数据双向绑定,千万不要混淆)
    vue中data为什么是函数而不是对象
    vue-enum 前端常量 枚举工具
    Vue3 写业务逻辑不适合用TS(TypeScript)
    vue-property-decorator vue3 ts 用的装饰器
    github git clone下载加速 && npm install 下载加速
    vue3 如果用ts,导出时候要用 defineComponent,这俩是配对的,为了类型的审查正确
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/11994742.html
Copyright © 2020-2023  润新知