1. 程式人生 > >一起來學SpringBoot | 第十九篇:輕鬆搞定資料驗證(一)

一起來學SpringBoot | 第十九篇:輕鬆搞定資料驗證(一)

SpringBoot是為了簡化Spring應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程

對於任何一個應用而言,客戶端做的資料有效性驗證都不是安全有效的,而資料驗證又是一個企業級專案架構上最為基礎的功能模組,這時候就要求我們在服務端接收到資料的時候也對資料的有效性進行驗證。為什麼這麼說呢?往往我們在編寫程式的時候都會感覺後臺的驗證無關緊要,畢竟客戶端已經做過驗證了,後端沒必要在浪費資源對資料進行驗證了,但恰恰是這種思維最為容易被別人鑽空子。畢竟只要有點開發經驗的都知道,我們完全可以模擬HTTP

請求到後臺地址,模擬請求過程中傳送一些涉及系統安全的資料到後臺,後果可想而知….

為什麼要輕鬆搞定?

相信通過上面的閱讀,大家對資料驗證的重要性有了一定的瞭解,那麼為什麼我這裡要說輕鬆搞定呢?

下面這段程式碼很多人一定見到過,就是對引數進行有效性校驗,但仔細觀察的話就會發現;隨著引數的增加,格式的變化,校驗資料有效性的程式碼愈發的繁瑣雜亂,一點都不輕鬆

public String test1(String name) {
    if (name == null) {
        throw new NullPointerException("name 不能為空");
    }
    if
(name.length() < 2 || name.length() > 10) { throw new RuntimeException("name 長度必須在 2 - 10 之間"); } return "success"; }

本章目標

通過Spring Boot完成引數後臺資料校驗,輕鬆搞定資料有效性驗證,留出更多的時間來和小姐姐聊天…

具體程式碼

通過上面的閱讀大家也大致能瞭解到為啥需要對異常進行全域性捕獲了,接下來就看看Spring Boot提供的解決方案

匯入依賴

pom.xml中新增上spring-boot-starter-web

的依賴即可

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

JSR-303 註釋介紹

這裡只列舉了javax.validation包下的註解,同理在spring-boot-starter-web包中也存在hibernate-validator驗證包,裡面包含了一些javax.validation沒有的註解,有興趣的可以看看

註解 說明
@NotNull 限制必須不為null
@NotEmpty 驗證註解的元素值不為 null 且不為空(字串長度不為0、集合大小不為0)
@NotBlank 驗證註解的元素值不為空(不為null、去除首位空格後長度為0),不同於@NotEmpty,@NotBlank只應用於字串且在比較時會去除字串的空格
@Pattern(value) 限制必須符合指定的正則表示式
@Size(max,min) 限制字元長度必須在 min 到 max 之間(也可以用在集合上)
@Email 驗證註解的元素值是Email,也可以通過正則表示式和flag指定自定義的email格式
@Max(value) 限制必須為一個不大於指定值的數字
@Min(value) 限制必須為一個不小於指定值的數字
@DecimalMax(value) 限制必須為一個不大於指定值的數字
@DecimalMin(value) 限制必須為一個不小於指定值的數字
@Null 限制只能為null(很少用)
@AssertFalse 限制必須為false (很少用)
@AssertTrue 限制必須為true (很少用)
@Past 限制必須是一個過去的日期
@Future 限制必須是一個將來的日期
@Digits(integer,fraction) 限制必須為一個小數,且整數部分的位數不能超過 integer,小數部分的位數不能超過 fraction (很少用)

實體類

為了體現validation的強大,分別演示普通引數屬性驗證與物件的驗證

package com.winterchen.pojo;

import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

/**
 * Created by Donghua.Chen on 2018/7/24.
 */
public class Book {

    private Integer id;
    @NotBlank(message = "name 不允許為空")
    @Length(min = 2, max = 10, message = "name 長度必須在 {min} - {max} 之間")
    private String name;
    @NotNull(message = "price 不允許為空")
    @DecimalMin(value = "0.1", message = "價格不能低於 {value}")
    private BigDecimal price;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}

控制層

與前面的程式碼相比,新的程式碼中僅僅多了幾個註解而已。(此處只是為了圖方便寫在了 Controller 層,同理你可以將它作用在 Service 層)

註解介紹

  • @Validated:開啟資料有效性校驗,新增在類上即為驗證方法,新增在方法引數中即為驗證引數物件。(新增在方法上無效)
  • @NotBlank:被註釋的字串不允許為空(value.trim() > 0 ? true : false
  • @Length:被註釋的字串的大小必須在指定的範圍內
  • @NotNull:被註釋的欄位不允許為空(value != null ? true : false)
  • @DecimalMin:被註釋的欄位必須大於或等於指定的數值
package com.winterchen.controller;

import com.winterchen.pojo.Book;
import org.hibernate.validator.constraints.Length;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotBlank;

/**
 * Created by Donghua.Chen on 2018/7/25.
 */
@Validated
@RestController
public class ValidateController {

    @GetMapping("/test2")
    public String test2(@NotBlank(message = "name 不能為空") @Length(min = 2, max = 10, message = "name 長度必須在 {min} - {max} 之間") String name) {
        return "success";
    }

    @GetMapping("/test3")
    public String test3(@Validated Book book) {
        return "success";
    }
}

主函式

package com.winterchen;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootValidation1Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootValidation1Application.class, args);
    }
}

測試

完成準備事項後,啟動Chapter18Application自行測試即可,測試手段相信大夥都不陌生了,如瀏覽器postmanjunitswagger,此處基於postman,如果你覺得自帶的異常資訊不夠友好,那麼配上一起來學SpringBoot | 第十八篇:輕鬆搞定全域性異常可以輕鬆搞定…

test2介面(name引數沒傳)

test2介面

test3介面(price引數值過低)

test3介面

總結

目前很多大佬都寫過關於SpringBoot的教程了,如有雷同,請多多包涵,本教程基於最新的spring-boot-starter-parent:2.0.2.RELEASE編寫,包括新版本的特性都會一起介紹…

說點什麼

springboot技術交流群:681513531