關於@Valid註解大全以及用法規范

@Valid註解大全及用法規范

註解 描述
@AssertFalse 帶註解的元素必須為false,支持boolean/Boolean
@AssertTrue 帶註解的元素必須為true,支持boolean/Boolean
@DecimalMax 帶註解的元素必須是一個數字,其值必須小於等於指定的最大值
@DecimalMin 帶註解的元素必須是一個數字,其值必須大於等於指定的最小值
@Digits 帶註解的元素必須是一個可接受范圍內的數字
@Future 帶註解的元素必須是將來的某個時刻、日期或時間
@Max 帶註解的元素必須是一個數字,其值必須小於等於指定的最大值
@Min 帶註解的元素必須是一個數字,其值必須大於等於指定的最小值
@NotNull 帶註解的元素不能是Null
@Null 帶註解的元素必須是Null
@Past 帶註解的元素必須是過去的某個時刻、日期或時間
@Pattern 帶註解的元素必須符合指定的正則表達式
@Size 帶註解的元素必須大於等於指定的最小值,小於等於指定的最大值
@Email 帶註解的元素必須是格式良好的電子郵箱地址
@NotEmpty 帶註解的元素不能是空,String類型不能為null,Array、Map不能為空,切size/length大於0
@NotBlank 字符串不能為空、空字符串、全空格
@URL 字符串必須是一個URL

@Valid註解規范用戶請求的參數

業務場景

對於一個用戶的註冊操作(Post請求),往往涉及到賬號(username)、密碼(password)的Post提交:

//用戶發送POST請求創建新的用戶
@PostMapping
public User create(@RequestBody User user){
    /**
        一些數據持久化操作,如:寫入數據庫
    **/
    //打印用戶提交的信息
    System.out.println(user.getId());
    System.out.println(user.getUsername());
    System.out.println(user.getPassword());
    System.out.println(user.getBirthday());
    return user;
}

業務出現的問題

但用戶往往會不小心提交瞭空的密碼來註冊,這是不允許的,因此我們往往需要對用戶提交的密碼信息進行空判斷,常見的方法是直接進行if語句的空判斷:

//用戶發送POST請求創建新的用戶
@PostMapping
public User create(@RequestBody User user){
    if( StringUtils.isBlank(user.getPassword())){
        //用戶輸入密碼為空,進行異常處理
    }
    /**
        一些數據持久化操作,如:寫入數據庫
    **/
    //打印用戶提交的信息
    System.out.println(user.getId());
    System.out.println(user.getUsername());
    System.out.println(user.getPassword());
    System.out.println(user.getBirthday());
    return user;
}

以上方法看似行得通,但一旦Post的方法變多,則需要對每個Post請求都進行一次if判斷是否為空,代碼變得冗餘,而且一旦修改一個地方,所有if語句都需要修改,可維護性就變得很差。

優化的解決方案

那麼,有沒有一種方法可以一勞永逸、既沒有大量代碼冗餘,可維護性又好呢?這時 javax.validation包下的@Valid註解就派上用場瞭。

1.首先,我們在實體類User.java中的密碼(password)屬性加上@NotBlank註解(hibernate.validator.constraints包)

import org.hibernate.validator.constraints.NotBlank;
public class User {
    public interface UserSimpleView{}
    public interface UserDetailView extends UserSimpleView{}
    private String username;
    //給該屬性加入NotBlank非空的約束
    @NotBlank
    private String password;
    private String id;
    private Date birthday;
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    @JsonView(UserSimpleView.class)
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    @JsonView(UserSimpleView.class)
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    @JsonView(UserDetailView.class)
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

2.我們在Controller類的Post方法的參數中加入@Valid註解,並使用BindingResult將錯誤信息作為日志打印到後臺

@PostMapping
public User create(@Valid @RequestBody User user,
                       BindingResult errors){
    if (errors.hasErrors()){
        //異常處理
        errors.getAllErrors().stream().forEach(error -> System.out.println(error.getDefaultMessage()));
    }
    user.setId("1");
    System.out.println(user.getId());
    System.out.println(user.getUsername());
    System.out.println(user.getPassword());
    System.out.println(user.getBirthday());
    return user;
}

3.這時,當我們向服務器Post提交空的密碼信息時,後臺會打印出錯誤信息:

may not be empty

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: