1. 程式人生 > >SpringMVC中引數校驗使用教程

SpringMVC中引數校驗使用教程

一、環境準備

在專案中新增以下依賴

gradle

org.hibernate:hibernate-validator:5.3.5.Final

maven

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.3.5.Final</version>
</dependency>

如果是SpringBoot專案,只需要引入web的starter即可,裡面包含了所需依賴

二、常用的校驗註解及示例

    //該引數必須為空
    @Null(message = "無需ID")
    private Integer id;

    //根據正則校驗手機號是否是由數字組成
    @Pattern(regexp = "^\\d{11}$", message = "手機格式不正確,不是11位")
    private String telephone;

    //校驗該物件是否為null
    //對於String來說,空字串可通過校驗,所以String應該使用@NotBlank進行校驗,此處僅做示例而已。
    @NotNull(message = "聯絡人不能為空")
    private String friendName;

    //校驗物件是否是空物件,可用於Array,Collection,Map,String
    @NotEmpty(message = "家庭成員不能為空")
    private List families;

    //校驗長度,可以用於Array,Collection,Map,String
    @Size(min = 4, max = 8, message = "使用者名稱長度錯誤 by size")
    //校驗長度,只能用於String
    @Length(min = 4, max = 8, message = "使用者名稱長度錯誤 by length")
    private String username;

    //javax校驗
    @Max(value = 200, message = "年齡一般不會超過200 by max")
    @Min(value = 1, message = "年齡一般不能小於1 by min")
    //hibernate校驗,效果等同
    @Range(min = 0, max = 200, message = "年齡範圍在0-200之間 by range")
    private Integer age;

    //校驗引數是否是False, 相反的是@AssertTrue
    @AssertFalse(message = "使用者初始化無需凍結")
    private Boolean lock;

    //String專用
    @NotBlank(message = "密碼不能為空")
    @Size(min = 6, max = 12, message = "密碼長度不對")
    private String password;

    //使用自定義校驗註解->校驗時間
    @Past(message = "生日只能為以前的時間")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date birth;

    //校驗Email
    @Email(message = "郵件地址不正確")
    private String email;

三、校驗類方法中的普通引數

  1. 在類上加@Validated註解
  2. 在引數上加上校驗註解

以controller層作示例如下:

@Validated
@RestController
@RequestMapping(value = "/user")
public class UserController {

    /**
     * 校驗請求引數
     */
    @GetMapping
    public String getUser(@Size(min = 5, max = 8, message = "使用者名稱長度超出限制") String username) {
	 return username;       
    }
}

四、校驗類方法中的自定義物件

  1. 在類上加@Validated註解(同普通引數一樣都需要加)
  2. 在引數上加@Valid,(或者加@Validated也是可以的)
@Validated
@RestController
@RequestMapping(value = "/user")
public class UserController {

    /**
     * 校驗請求中的自定義物件
     */
    @PostMapping
    public UserDTO saveUserOuter(@RequestBody @Valid UserDTO userDTO) {
        return userDTO;
    }

}

3.在自定義物件中的屬性上加上校驗註解

public class UserDTO {

    //該引數必須為空
    @Null(message = "無需ID")
    private Integer id;

    //根據正則校驗手機號是否是由數字組成
    @Pattern(regexp = "^\\d{11}$", message = "手機格式不正確,不是11位")
    private String telephone;

    //校驗該物件是否為null
    //對於String來說,空字串可通過校驗,所以String應該使用@NotBlank進行校驗,此處僅做示例而已。
    @NotNull(message = "聯絡人不能為空")
    private String friendName;

    //校驗物件是否是空物件,可用於Array,Collection,Map,String
    @NotEmpty(message = "家庭成員不能為空")
    private List families;

    //校驗長度,可以用於Array,Collection,Map,String
    @Size(min = 4, max = 8, message = "使用者名稱長度錯誤 by size")
    //校驗長度,只能用於String
    @Length(min = 4, max = 8, message = "使用者名稱長度錯誤 by length")
    private String username;

    //javax校驗
    @Max(value = 200, message = "年齡一般不會超過200 by max")
    @Min(value = 1, message = "年齡一般不能小於1 by min")
    //hibernate校驗,效果等同
    @Range(min = 0, max = 200, message = "年齡範圍在0-200之間 by range")
    private Integer age;

    //校驗引數是否是False, 相反的是@AssertTrue
    @AssertFalse(message = "使用者初始化無需凍結")
    private Boolean lock;

    //String專用
    @NotBlank(message = "密碼不能為空")
    @Size(min = 6, max = 12, message = "密碼長度不對")
    private String password;

    //使用自定義校驗註解->校驗時間
    @Past(message = "生日只能為以前的時間")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date birth;

    //校驗Email
    @Email(message = "郵件地址不正確")
    private String email;

	//setter  getter ....
}

五、關於@Valid和@Validated的區別聯絡

一直對@Valid和@Validated這兩個註解非常疑惑,不知道怎麼區分和使用。

1.包位置

  • @Valid: javax.validation, 是javax,也是就是jsr303中定義的規範註解
  • @Validated: org.springframework.validation.annotation, 是spring自己封裝的註解。

2.功能
@Valid就不用說了,是jsr303的規範。我們開啟@Validated的原始碼,可以看到以下注釋,

Variant of JSR-303's {@link javax.validation.Valid}, supporting the
specification of validation groups. Designed for convenient use with
Spring's JSR-303 support but not JSR-303 specific.

大致意思就是說@Validated是@Valid的一個變種,擴充套件了@Valid的功能,支援group分組校驗的寫法。
那麼我們對於@Valid和@Validated就可以這麼理解:

  1. 能用@Valid的地方通常可以用@Validated替代。
  2. 需要使用分組校驗的時候使用@Validated註解。

六、分組校驗

我們有一個使用者DTO,其中有id,username兩個屬性。當儲存時,id不需要有值,由資料庫自動生成,我們使用@Null註解校驗。當更新時,id需要有值,根據ID去更新使用者名稱,我們使用@NotNull註解校驗。無論是儲存使用者還是更新使用者,都需要校驗使用者名稱,我們使用@NotBlank註解校驗。

UserGroupValidDTO

public class UserGroupValidDTO {

    public interface SaveGroup extends Default {}

    public interface UpdateGroup extends Default {}

    @Null(groups = {SaveGroup.class}, message = "不需要傳入使用者ID")
    @NotNull(groups = {UpdateGroup.class}, message = "使用者ID不能為空")
    private Integer id;

    @NotBlank(message = "使用者名稱不能為空")
    private String username;
    
    //Setter Getter ...
}

定義相應型別的公開介面(SaveGroup,UpdateGroup),給每個校驗註解指定groups屬性,如果不指定則預設為javax.validation.groups.Default.class。

我們讓SaveGroup和UpdateGroup繼承了Default, 那麼三個介面之間的關係類似如下:

save --> SaveGroup |-->id  @Null
                   |-->Default --> username @NotBlank
                   
update--> UpdateGroup |-->id @NotNull
                      |-->Default --> username @NotBlank

UserController

@Validated
@RestController
@RequestMapping(value = "/user")
public class UserController {
    /**
     * 分組校驗:儲存使用者,不能傳ID
     */
    @PostMapping("/save")
    public void validSaveUser(@RequestBody @Validated(value = UserGroupValidDTO.SaveGroup.class) UserGroupValidDTO userDTO) {
        //save user
    }

    /**
     * 分組校驗:更新使用者資訊,需要傳ID
     */
    @PostMapping("/update")
    public void validUpdateUser(@RequestBody @Validated(value = UserGroupValidDTO.UpdateGroup.class) UserGroupValidDTO userDTO) {
        //update user
    }

}

在方法引數的物件上加@Validated屬性,填寫Value為對應的介面的class即可,這時候訪問不同的介面就會進行不同的校驗了。

七、自定義校驗註解

有時候預設提供的校驗註解無法滿足我們的需要,我們需要自定義。例如現有校驗註解不支援java8中的LocalDateTime。那麼接下來我們自定義一個校驗LocalDateTime的註解。該註解判斷傳入的時間是否是一個過去的時間。

1.建立校驗註解

/**
 * @author [email protected]
 * @date 2017/12/29 下午7:24
 * @desc ${DESCRIPTION}.
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PastTimeValidate.class)
public @interface PastDate {

    String message();

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };

}

2.編寫校驗規則
校驗規則也就是列舉PastDate中指定的validateBy屬性

/**
 * @author [email protected]
 * @date 2017/12/29 下午7:28
 * @desc .
 */
@CommonsLog
public class PastTimeValidate implements ConstraintValidator<PastDate, LocalDateTime> {

   @Override
   public void initialize(PastDate constraintAnnotation) {
      log.info("init enum PastDate");
   }

   @Override
   public boolean isValid(LocalDateTime localDateTime, ConstraintValidatorContext context) {
      return localDateTime.isBefore(LocalDateTime.now()) ? true : false;
   }
}

寫完這些,我們就可以像@Past對Date校驗一樣使用@PastDate對LocalDateTime進行校驗了。

可以參考我的github專案檢視完整示例,示例中額外包含了校驗異常的捕捉方式。

相關推薦

SpringMVC引數使用教程

一、環境準備 在專案中新增以下依賴 gradle org.hibernate:hibernate-validator:5.3.5.Final maven <dependency> <groupId>org.hibernate&l

springmvc、springboot 引數

引數校驗在專案中是必不可少的,不僅前端需要校驗,為了程式的可靠性,後端也需要對引數進行有效性的校驗。下面將介紹在springmvc或springboot專案中引數校驗的方法 準備工作: 引入校驗需要用到的依賴    首先放上我們的測試物件 方法一、

SpringMVC自定義註解進行引數

在我的另一篇部落格中(SpringMVC),學習瞭如何使用Spring MVC結合Hibernate的校驗框架validation(它和hibernate沒有任何關係)對引數進行校驗。在實際專案中,引數的校驗邏輯可能比較複雜,這時我們可以自定義註解來實現引數校驗,下面是一個簡單的例子。 po

SpringMVC自定義註解進行引數(以列舉值是否合法為例)

pom引入springMVC依賴,以springboot專案為例 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-

在springboot使用統一引數

開發web專案有時候我們需要對controller層傳過來的引數進行一些基本的校驗,比如非空,非null,整數值的範圍,字串的個數,日期,郵箱等等。最常見的就是我們直接寫程式碼校驗,這樣以後比較繁瑣,而且不夠靈活。 Bean Validation 1.0(JSR

【hibernate-validator+SpringMVC】後臺引數框架

hibernate-validator+SpringMVC簡介:簡單說,就是對Entity進行校驗。1、導包,沒有很嚴謹的對應關係,所以我用了比較新的版本,支援更多的註解。  <dependency> <groupId&

如何從 if-else 的引數解放出來?

背景 在開發中經常需要寫一些欄位校驗的程式碼,比如非空,長度限制,郵箱格式驗證等等,導致充滿了if-else 的程式碼,不僅相當冗長,而且很讓人抓狂。 hibernate validator(官方文件)提供了一套比較完善、便捷的驗證實現方式。它定義了很多常用的校驗註解,我們可以直接將這些註解加在我們Jav

Spring Boot 2.x基礎教程:JSR-303實現請求引數

請求引數的校驗是很多新手開發非常容易犯錯,或存在較多改進點的常見場景。比較常見的問題主要表現在以下幾個方面: 僅依靠前端框架解決引數校驗,缺失服務端的校驗。這種情況常見於需要同時開發前後端的時候,雖然程式的正常使用不會有問題,但是開發者忽略了非正常操作。比如繞過前端程式,直接模擬客戶端請求,這時候就會突然在

如何在 Spring/Spring Boot 引數?你需要了解的都在這裡!

本文為作者原創,如需轉載請在文首著名地址,公眾號轉載請申請開白。 springboot-guide : 適合新手入門以及有經驗的開發人員查閱的 Spring Boot 教程(業餘時間維護中,歡迎一起維護)。 資料的校驗的重要性就不用說了,即使在前端對資料進行校驗的情況下,我們還是要對傳入後端的資料再進行一

SpringMVC引數

**** > SpringMVC是根據引數的名字,然後用setter方法來對資料進行繫結的,若型別沒有匹配上則會出現400的錯誤,同時還要注意空值問題 ## 1. 引數校驗 我們在做Web層的時候,接收了各種引數,儘管前端已經做了驗證,但難免惡意傳參,所以要對傳過來的資料保持不信任的態度來

測試開發專題:如何在spring-boot進行引數

上文我們討論了spring-boot如何去獲取前端傳遞過來的引數,那傳遞過來總不能直接使用,需要對這些引數進行校驗,符合程式的要求才會進行下一步的處理,所以本篇文章我們主要討論spring-boot中如何進行引數校驗。 ### lombok使用介紹 在介紹引數校驗之前,先來了解一下lombok的使用,因為

SpringMVC——數據

pre exp blank ann delattr base 名稱 user 正則 數據校驗在web應用裏是非常重要的功能,尤其是在表單輸入中。在這裏采用Hibernate-Validator進行校驗,該方法實現了JSR-303驗證框架支持註解風格的驗證。 一、導入jar包

SpringMVC數據

相關 業務 思路 pre max idt flag decimal 沒有 一、準備 1.1 校驗理解 項目中,通常使用較多的是前端的校驗,比如頁面中js校驗。對於安全要求較高建議在服務端進行校驗。服務端校驗有: 控制層:校驗頁面請求的參數的合法性。在服務端校驗不區分客戶端

Vue 元件引數與非 props 特性

元件的引數校驗:父元件通過屬性傳遞給子元件資料,子元件有權對這些資料進行約束,這就是引數校驗。 如下,簡單的引數校驗。 <div id="root"> <child content="hello world"></child> <!-- 下

日誌資訊新增和引數

1:在類中要新增日誌資訊: private static final Logger log = LogManager.getLogger(ShopCartAction.class); log.info();//普通訊息 log.error();//錯誤資訊列印 log.debug()

Spring基礎系列-引數

原創作品,可以轉載,但是請標註出處地址:https://www.cnblogs.com/V1haoge/p/9953744.html Spring中使用引數校驗 概述 ​ JSR 303中提出了Bean Validation,表示JavaBean的校驗,Hibernate Validation是其具體實

Java Bean Validation 引數

引數校驗是我們程式開發中必不可少的過程。使用者在前端頁面上填寫表單時,前端js程式會校驗引數的合法性,當資料到了後端,為了防止惡意操作,保持程式的健壯性,後端同樣需要對資料進行校驗。後端引數校驗最簡單的做法是直接在業務方法裡面進行判斷,當判斷成功之後再繼續往下執行。但這樣帶給我們的是程式碼的耦合,冗

SpringBoot引數--List型別

一般我們定義了DTO來接收引數,然後使用@validated來驗證DTO裡面的校驗規則。當我們的介面接收的引數為List<E>時,可以使用本文的方法進行校驗。 包含驗證規則的實體類: import io.swagger.annotations.ApiModel; i

ssm引數

方法一:使用hibernate-validate框架,使用起來較為麻煩(SpringMVC官方推薦); 方法二:使用aop面向切面和自定義註解; 攔截器與aop:      aop可以取得被代理方法的物件和引數,而攔截器需要從請求中取值在校驗,且校驗規

Spring註釋積累

註解的定義(在4.1版中): 1,@ NOTNULL: 定義如下: @Constraint(validatedBy = {NotNullValidator.class}) 這個類中有一個isValid方法方法是這麼定義的: public boolean isValid(Obj