• JSR 303 数据校验以及放入统一的返回结果


    一、介绍

    JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。

    二、普通使用步骤

    1. 给Bean添加校验注解:javax.validation.constraints,并自定义 message提示

          /**
           * 品牌名
           */
          @NotBlank(message = "品牌名必须提交")
          private String name;
      
    2. 在Controller层添加校验功能 @Valid

          /**
           * 保存
           */
          @RequestMapping("/save")
          public R save(@Valid @RequestBody BrandEntity brand) {
              brandService.save(brand);
              return R.ok();
          }
      
    3. 效果:在postman测试,会有默认的响应

      {
          "timestamp": "2020-04-21T03:53:31.757+0000",
          "status": 400,
          "error": "Bad Request",
          "errors": [
              {
                  "codes": [
                      "NotBlank.brandEntity.name",
                      "NotBlank.name",
                      "NotBlank.java.lang.String",
                      "NotBlank"
                  ],
                  "arguments": [
                      {
                          "codes": [
                              "brandEntity.name",
                              "name"
                          ],
                          "arguments": null,
                          "defaultMessage": "name",
                          "code": "name"
                      }
                  ],
                  "defaultMessage": "品牌名必须提交",
                  "objectName": "brandEntity",
                  "field": "name",
                  "rejectedValue": "",
                  "bindingFailure": false,
                  "code": "NotBlank"
              }
          ],
          "message": "Validation failed for object='brandEntity'. Error count: 1",
          "path": "/product/brand/save"
      }
      

    三、封装到统一返回结果

    对实体类注明校验字段

    @Data
    @TableName("pms_brand")
    public class BrandEntity implements Serializable {
        private static final long serialVersionUID = 1L;
    
        /**
         * 品牌id
         */
        @TableId
        private Long brandId;
        /**
         * 品牌名
         */
        @NotBlank(message = "品牌名必须提交")
        private String name;
        /**
         * 品牌logo地址
         */
        @NotEmpty
        @URL(message = "logo 必须是合法url地址")
        private String logo;
        /**
         * 介绍
         */
        private String descript;
        /**
         * 显示状态[0-不显示;1-显示]
         */
        private Integer showStatus;
        /**
         * 检索首字母
         */
        @NotEmpty
        @Pattern(regexp = "/^[a-zA-Z]$/", message = "检索首字母必须是一个字母")
        private String firstLetter;
        /**
         * 排序
         */
        @NotNull
        @Min(value = 0, message = "排序必须大于等于0")
        private Integer sort;
    
    }
    

    对Controller方法做处理

    BindingResult 是处理的校验结果,对此分析并放入统一的返回结果里

    /**
         * 保存
         *
         * @param brand
         * @param result 校验结果
         * @return
         */
    @RequestMapping("/save")
    // @RequiresPermissions("product:brand:save")
    public R save(@Valid @RequestBody BrandEntity brand, BindingResult result) {
        if (result.hasErrors()) {
            Map<String, String> map = new HashMap<>();
            // 获取校验的错误结果
            result.getFieldErrors().forEach((item) -> {
                // 错误提示
                String message = item.getDefaultMessage();
                // 错误的属性名
                String field = item.getField();
                map.put(field, message);
            });
            return R.error(400, "提交的数据不合法").put("data", map);
        }
        brandService.save(brand);
        return R.ok();
    }
    

    测试结果

    ```json
    {
        "msg": "提交的数据不合法",
        "code": 400,
        "data": {
            "logo": "不能为空",
            "sort": "不能为null",
            "firstLetter": "不能为空"
        }
    }
    ```
    

    四、分组校验

    一个字段在不同情况下会有不同校验逻辑,比如id,在新增时不用填写,此时数据库里是自增的,但更新时则必须填写,此时可以对它们标注分组以区分不同的情况。

    对实体类注明校验字段

    在字段上指定不同的情况下的校验情况,分组是一个空接口,仅用以区分

        /**
         * 品牌id
         */
        @NotNull(message = "修改必须指定品牌id", groups = {UpdateGroup.class})
        @Null(message = "新增不能指定品牌id", groups = {AddGroup.class})
        @TableId
        private Long brandId;
        /**
         * 品牌名
         */
        @NotBlank(message = "品牌名必须提交", groups = {UpdateGroup.class, AddGroup.class})
        private String name;
        /**
         * 品牌logo地址
         */
        @NotBlank(groups = {AddGroup.class})
        @URL(message = "logo 必须是合法url地址", groups = {AddGroup.class, UpdateGroup.class})
        private String logo;
        /**
         * 介绍
         */
        private String descript;
        /**
         * 显示状态[0-不显示;1-显示]
         */
        private Integer showStatus;
        /**
         * 检索首字母
         */
        @NotEmpty(groups = {AddGroup.class})
        @Pattern(regexp = "/^[a-zA-Z]$/", message = "检索首字母必须是一个字母", groups = {UpdateGroup.class, AddGroup.class})
        private String firstLetter;
        /**
         * 排序
         */
        @NotNull(groups = {AddGroup.class})
        @Min(value = 0, message = "排序必须大于等于0", groups = {UpdateGroup.class, AddGroup.class})
        private Integer sort;
    

    对Controller方法做处理

    把之前的 JSR303提供的接口@Valid 变为 Spring提供的实现 @Validated。在不同方法上注明不同的情况

    /**
     * 保存
     *
     * @param brand
     * @return
     */
    @RequestMapping("/save")
    public R save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand) {
        brandService.save(brand);
        return R.ok();
    }
    
    /**
     * 修改
     */
    @RequestMapping("/update")
    // @RequiresPermissions("product:brand:update")
    public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand) {
        brandService.updateById(brand);
    
        return R.ok();
    }
    
    没有修不好的电脑
  • 相关阅读:
    UOJ#310. 【UNR #2】黎明前的巧克力(FWT)
    cf24D. Broken robot(高斯消元)
    loj#2483. 「CEOI2017」Building Bridges(dp cdq 凸包)
    给博客园加一个会动的小人-spig.js
    loj#6033. 「雅礼集训 2017 Day2」棋盘游戏(二分图博弈)
    loj#6032. 「雅礼集训 2017 Day2」水箱(并查集 贪心 扫描线)
    洛谷P4103 [HEOI2014]大工程(虚树 树形dp)
    Oracle DB SQL 性能分析器
    ORA-000845 与 /dev/shm(tempfs)
    ID3DXMesh接口 创建自己的立方体网格
  • 原文地址:https://www.cnblogs.com/duniqb/p/12743798.html
Copyright © 2020-2023  润新知