Springboot之前端參數驗證

對於任何一個應用而言,在客戶端做的數據有效性驗證主要目的是規範用戶的輸入,而真實的數據驗證工作都是在服務後端代碼當中實現的,但在實際的項目當中,也經常會因爲各種各樣的原因:懶得寫,覺得前端驗證了,後端沒有太多的必要等等沒有進行數據驗證,其實養成數據的有效性驗證是一個非常好的習慣。
1 可以避免很多數據有效性導致的BUG,防範其餘開發者的基礎攻擊
2 在前後端進行接口聯調的時候,不需要因爲參數的問題溝通很久。

springboot 參數驗證

JSR-303 是 JAVA EE 6 中的一項子規範,叫做 Bean Validation,官方參考實現是Hibernate Validator。JSR 303 用於對 Java Bean 中的字段的值進行驗證。 主要是 javax.validation 包下面的註解,用於進行參數的驗證。在 spring-boot當中存在 hibernate-validator 驗證包,這個包裏面包含了一些 javax.validation 沒有的註解。算是spring對於JSR驗證的的擴展吧!

常用驗證註解:

註解 用法
@NotNull 限制必須不爲null
@Null 限制必須爲null
@NotEmpty 驗證註解的元素值不爲 null 且不爲空(字符串長度不爲0、集合大小不爲0)
@NotBlank @NotBlank只應用於字符串且在比較時會去除字符串的空格
@Size(min,max) 限制字符串或者集合長度必須在 min 到 max 之間
@Max(value) 限制必須爲一個不大於指定值的數字
@Min(value) 限制必須爲一個不小於指定值的數字
@Past 限制必須是一個過去的日期
@Future 限制必須是一個將來的日期
@Email 驗證註解的元素值是Email,可以通過正則表達式和flag指定自定義的email格式
@Pattern(value) 限制必須符合指定的正則表達式

參數驗證具體使用

1 創建需要驗證的實體類


/**
 * @author 海加爾金鷹
 */
@Data
public class TestVo {

    @NotNull(message = "id 不能爲空")
    private Integer id;

    @NotBlank(message = "name 不能爲空字符串")
    private String name;

    @NotEmpty(message = "empty不能爲空集合")
    private List<String> empty;

    @Max(value = 99,message = "排序最大值不能超過99")
    private int sort;
}

2 創建對應的請求接口 在需要校驗的參數上加上@valid註解或者加上@Validated 註解 備註(由於是測試所有這裏不加上BindingResult 參數)

/**
 * @author 海加爾金鷹
 */
@RestController
public class TestController {
    @GetMapping("/id")
    public TestVo getTestVo(@RequestBody @Valid TestVo vo){
        return vo;
    }
}

3 發送請求查詢返回的信息

GET http://localhost:8080/id
Content-Type: application/json

{
 "name" : "content",
  "sort": 55
 }
   "errors": [
    {
      "codes": [
        "NotEmpty.testVo.empty",
        "NotEmpty.empty",
        "NotEmpty.java.util.List",
        "NotEmpty"
      ],
      "arguments": [
        {
          "codes": [
            "testVo.empty",
            "empty"
          ],
          "arguments": null,
          "defaultMessage": "empty",
          "code": "empty"
        }
      ],
      "defaultMessage": "empty不能爲空集合",
      "objectName": "testVo",
      "field": "empty",
      "rejectedValue": null,
      "bindingFailure": false,
      "code": "NotEmpty"
    },
    {
      "codes": [
        "NotNull.testVo.id",
        "NotNull.id",
        "NotNull.java.lang.Integer",
        "NotNull"
      ],
      "arguments": [
        {
          "codes": [
            "testVo.id",
            "id"
          ],
          "arguments": null,
          "defaultMessage": "id",
          "code": "id"
        }
      ],
      "defaultMessage": "id 不能爲空",
      "objectName": "testVo",
      "field": "id",
      "rejectedValue": null,
      "bindingFailure": false,
      "code": "NotNull"
    }
  ]

springboot參數的驗證就成功的實現了。很簡單,不復雜。

注意事項

  • @valid 這個註解是JSR-303 規範原生的驗證註解 @Validated 註解是spring針對@valid 進行的一個封裝,提供了一些額外的功能。
  • 如果在接口上面加上了BindingResult 這個參數的話,驗證後的錯誤信息不會拋出來,會被封裝到這個類當中。 如果需要獲取到驗證的錯誤信息,需要從這個類手動當中獲取。
  • @Max @Min 在對包裝類型進行驗證的時候,如果包裝類爲null,是可以通過驗證的,需要配合@NotNull註解一起使用

springboot參數通過切面進行統一驗證返回

在測試用例當中,返回的數據格式非常不友好,通常實際情況下都是通過切面的方式,獲取BindingResult 參數的數據,如果有驗證錯誤信息,就返回給前端參數相關的錯誤的信息

/**
 * @author 海加爾金鷹
 */
@Aspect
@Component
public class BindingResultAspect {

    @Around("execution(* cn.hjljy.springboot.validdemo.controller.*.*(..)) && args(..,bindingResult)")
    public Object validateParam(ProceedingJoinPoint joinPoint, BindingResult bindingResult) throws Throwable {
        Object obj = null;
        if (bindingResult.hasErrors()) {
            // 有校驗錯誤  
            System.out.println(bindingResult.getAllErrors().toString());
            return "這裏返回錯誤的信息";
        } else {
            // 沒有錯誤方法繼續執行
            obj = joinPoint.proceed();
        }
        return obj;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章