1. 程式人生 > >Spring請求引數校驗

Spring請求引數校驗

SpringMVC支援的資料校驗是JSR303的標準,通過在bean的屬性上打上@NotNull@Max等進行驗證。JSR303提供有很多annotation介面,而SpringMVC對於這些驗證是使用hibernate的實現,所以我們需要新增hibernate的一個validator包:

依賴引用

compile 'javax.validation:validation-api:2.0.0.Final'
compile 'org.hibernate:hibernate-validator:6.0.0.Final'

框架已經提供校驗如下:

JSR提供的校驗註解:         
@Null   被註釋的元素必須為 null    
@NotNull    被註釋的元素必須不為 null,不能為 null , 可以為 ""    
@AssertTrue     被註釋的元素必須為 true    
@AssertFalse    被註釋的元素必須為 false    
@Min(value)     被註釋的元素必須是一個數字,其值必須大於等於指定的最小值    
@Max(value)     被註釋的元素必須是一個數字,其值必須小於等於指定的最大值    
@DecimalMin(value)  被註釋的元素必須是一個數字,其值必須大於等於指定的最小值    
@DecimalMax(value)  被註釋的元素必須是一個數字,其值必須小於等於指定的最大值    
@Size(max=, min=)   驗證物件(Array,Collection,Map,String)長度是否在給定的範圍之內    
@Digits (integer, fraction)     被註釋的元素必須是一個數字,其值必須在可接受的範圍內    
@Past   被註釋的元素必須是一個過去的日期    
@Future     被註釋的元素必須是一個將來的日期    
@Pattern(regex=,flag=)  被註釋的元素必須符合指定的正則表示式    

Hibernate Validator提供的校驗註解:  
@NotBlank(message =)   只能作用在String上,不能為null,而且呼叫trim()後,長度必須大於0    
@Email  被註釋的元素必須是電子郵箱地址    
@Length(min=,max=)  被註釋的字串的大小必須在指定的範圍內    
@NotEmpty   被註釋的字串的必須非空,不能為 null、"",可以為 " "    
@Range(min=,max=,message=)  被註釋的元素必須在合適的範圍內

例項演示

建立需要被校驗的實體類:

package com.yiba.wifi.news.bean.model;

import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.*;

public class User {

    @NotBlank(message = "使用者名稱不能為null,長度必須大於0")
    String name;   //使用者名稱

    @Min(value = 1, message = "最小年齡為1歲")
    @Max(value = 120, message = "最大年齡為120歲")
    Integer age;  //年齡

    @Email(message = "郵箱格式錯誤")
    @NotBlank(message = "郵箱格式錯誤")    
    String email;  //郵箱

    @Length(min = 6, max = 12, message = "密碼長度必須在6位到12位之間")
    String pwd;//密碼
    
    //get、set.........
}

注意在校驗郵箱的時候,當 email 為 "", 或者 null 的時候,會通過 @Email驗證,所以郵箱校驗需要 @Email@NotBlank 共同起作用。

controller 介面設計,在引數接受的地方新增 @Validated 關鍵字

 /**
     * 登入介面
     * @return
     */
    @PostMapping("login")
    public String login(@Validated @RequestBody User user) {
        return "ok";
    }

訪問測試:
當訪問資料是如下格式的時候

{
  "name": "",
  "age": 0,
  "email": "",
  "pwd": ""
}

響應為:

{
  "timestamp": 1524640724522,
  "status": 400,
  "error": "Bad Request",
  "exception": "org.springframework.web.bind.MethodArgumentNotValidException",
  "errors": [
    {
      "codes": [
        "NotBlank.user.email",
        "NotBlank.email",
        "NotBlank.java.lang.String",
        "NotBlank"
      ],
      "arguments": [
        {
          "codes": [
            "user.email",
            "email"
          ],
          "arguments": null,
          "defaultMessage": "email",
          "code": "email"
        }
      ],
      "defaultMessage": "郵箱格式錯誤",
      "objectName": "user",
      "field": "email",
      "rejectedValue": "",
      "bindingFailure": false,
      "code": "NotBlank"
    },
    {
      "codes": [
        "NotBlank.user.name",
        "NotBlank.name",
        "NotBlank.java.lang.String",
        "NotBlank"
      ],
      "arguments": [
        {
          "codes": [
            "user.name",
            "name"
          ],
          "arguments": null,
          "defaultMessage": "name",
          "code": "name"
        }
      ],
      "defaultMessage": "使用者名稱不能為null,長度必須大於0",
      "objectName": "user",
      "field": "name",
      "rejectedValue": "",
      "bindingFailure": false,
      "code": "NotBlank"
    },
    {
      "codes": [
        "Length.user.pwd",
        "Length.pwd",
        "Length.java.lang.String",
        "Length"
      ],
      "arguments": [
        {
          "codes": [
            "user.pwd",
            "pwd"
          ],
          "arguments": null,
          "defaultMessage": "pwd",
          "code": "pwd"
        },
        12,
        6
      ],
      "defaultMessage": "密碼長度必須在6位到12位之間",
      "objectName": "user",
      "field": "pwd",
      "rejectedValue": "",
      "bindingFailure": false,
      "code": "Length"
    },
    {
      "codes": [
        "Min.user.age",
        "Min.age",
        "Min.java.lang.Integer",
        "Min"
      ],
      "arguments": [
        {
          "codes": [
            "user.age",
            "age"
          ],
          "arguments": null,
          "defaultMessage": "age",
          "code": "age"
        },
        1
      ],
      "defaultMessage": "最小年齡為1歲",
      "objectName": "user",
      "field": "age",
      "rejectedValue": 0,
      "bindingFailure": false,
      "code": "Min"
    }
  ],
  "message": "Validation failed for object='user'. Error count: 4",
  "path": "/yiba/sms/login"
}

可以看到本地請求,4個欄位校驗都沒通過,那麼我有沒有辦法獲取異常資訊呢,答案是有的,需要我們修改 controller 介面。

  /**
     * 登入介面
     *
     * @return
     */
    @PostMapping("login")
    public String login(@Validated @RequestBody User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            //有校驗沒通過
            List<ObjectError> errorList = bindingResult.getAllErrors();
            for (ObjectError error : errorList) {
                System.out.println(error.getDefaultMessage());  //輸出具體的錯誤資訊
            }
            return "引數異常";
        }
        return "ok";
    }

再次請求,請求格式如下

{
  "name": "",
  "age": 0,
  "email": "",
  "pwd": ""
}

響應如下

引數異常

在控制檯列印的資訊如下:

使用者名稱不能為null,長度必須大於0
密碼長度必須在6位到12位之間
最小年齡為1歲
郵箱格式錯誤

可以看到我們已經正常的獲取到了校驗資訊了。

下面我們來做一次參照正確的訪問:
請求引數如下:

{
  "name": "zhaoyanjun",
  "age": 1,
  "email": "[email protected]",
  "pwd": "123456"
}

響應如下:

ok

控制檯什麼也沒輸出。

到這裡校驗已經講解完成了。

個人微訊號:zhaoyanjun125 , 歡迎關注