SpringBoot學習篇之@Valid與@Validated的區別

1.介紹

說明: 其實@Valid 與 @Validated都是做數據校驗的,隻不過註解位置與用法有點不同。

不同點:

(1)

@Valid是使用Hibernate validation的時候使用。@Validated是隻用Spring Validator校驗機制使用。

(2)

@Valid 可以嵌套驗證

@Validation 不能進行嵌套驗證

(3)

@Valid:可以用在方法、構造函數、方法參數和成員屬性(field)上。

@Validated:用在類、方法和方法參數上。但不能用於成員屬性(field)。

(如果@Validated註解在成員屬性上,則會報不適用於field的錯誤。)

(4)

@Valid:沒有分組功能。

@Validated:提供分組功能,可以在參數驗證時,根據不同的分組采用不同的驗證機制。

2.用法

(1)@Valid用法

a.導入依賴

SpringBoot項目:

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>
 
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.4.1.Final</version>
</dependency>

b.使用前提是實體類中屬性使用註解進行校驗

package com.example.demo.pojo;

import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;

//lombok
@Data
public class User implements Serializable {

    //用戶名
    @NotBlank(message = "請輸入名稱")
    @Length(message = "名稱不能超過個 {max} 字符", max = 10)
    private String username;

    //年齡
    @NotNull(message = "請輸入年齡")
    @Range(message = "年齡范圍為 {min} 到 {max} 之間", min = 1, max = 100)
    private String age;
}

c.在Controller方法參數中加上@Valid註解

package com.example.demo.controller;

import com.example.demo.pojo.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;

@RestController
public class UserController {

    public static final Logger logger = LoggerFactory.getLogger(UserController.class.getName());

    @PostMapping("/add")
    @ResponseBody
    public String add(@Validated User user, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            allErrors.forEach( v ->{
                logger.error(v.getObjectName()+"======"+v.getDefaultMessage());
            });
            return "添加失敗";
        }
        return "添加成功";
    }
}

經過測試填寫錯誤數據,會在控制臺輸出報錯信息。

(2)@Validated用法

a.開啟校驗框架(與上面一樣)

<!--1.導入JSR303規范-->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
</dependency>
<!--使用hibernate框架提供的校驗器做實現-->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
</dependency>

c.在需要開啟校驗功能的類上使用註解@Validated開啟校驗功能,對具體的字段設置校驗規則,這裡講的是可以在類上使用@Validated註解,配合xml數據綁定。

@Component
@Data
@ConfigurationProperties(prefix = "servers")
//開啟對當前bean的屬性註入校驗
@Validated
public class ServerConfig {
    //設置具體的規則
    @Max(value = 8888,message = "最大值不能超過8888")
    @Min(value = 202,message = "最小值不能低於202")
    private int port;
}

(3)@Validated實現分組校驗

註意 分組校驗就是把條件加入組中,可以自由選擇開啟那些組的校驗方式。

a.分組接口

package com.example.demo.pojo;
public interface Group {
    interface Update{};
    interface FindAll{};
}

b.實體類

package com.example.demo.pojo;

import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;

//lombok
@Data
public class User implements Serializable {

    //用戶名
    @NotBlank(message = "請輸入用戶名不能為空",groups = {Group.FindAll.class})
    @Length(message = "名稱不能超過個 {max} 字符", max = 10 ,groups = {Group.FindAll.class})
    private String username;

    //年齡
    @NotBlank(message = "請輸入年齡不能為空",groups = {Group.Update.class})
    @Range(message = "年齡范圍為 {min} 到 {max} 之間", min = 1, max = 100,groups = {Group.Update.class})
    private String age;
}

c.controller接口:

註意 @Validated有參數 value中寫分組名稱

package com.example.demo.controller;

import com.example.demo.pojo.Group;
import com.example.demo.pojo.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;

@RestController
public class UserController {

    public static final Logger logger = LoggerFactory.getLogger(UserController.class.getName());

    @PostMapping("/add")
    @ResponseBody
    //註意@Validated有參數 value中寫分組名稱
    public String add(@Validated(value = {Group.Update.class}) User user, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            allErrors.forEach( v ->{
                logger.error(v.getObjectName()+"======"+v.getDefaultMessage());
            });
            return "添加失敗";
        }
        return "添加成功";
    }
}

(4)@Valid 實現嵌套校驗

註: 嵌套檢測就是在一個User類中,存在另外一個User2類的屬性。嵌套檢測User同時也檢測User2。

a.實體類User

package com.example.demo.pojo;

import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;

//lombok
@Data
public class User implements Serializable {

    //用戶名
    @NotBlank(message = "請輸入用戶名不能為空1")
    private String username;

    //年齡
    @NotBlank(message = "請輸入年齡不能為空1")
    private String age;

    @Valid
    @NotNull(message = "user2不能為空1")
    private User2 user2;
}
}

b.實體類User2

package com.example.demo.pojo;

import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;

package com.example.demo.pojo;

import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotNull;
import java.io.Serializable;

//lombok
@Data
public class User2 implements Serializable {

    //用戶名
    @Length(message = "名稱不能超過個 {max} 字符2", max = 10 )
    private String username2;

    //年齡

    @Range(message = "年齡范圍為 {min} 到 {max} 之間2", min = 1, max = 100)
    private String age2;
}

c.Controller類(這裡使用@Valid)

package com.example.demo.controller;

import com.example.demo.pojo.Group;
import com.example.demo.pojo.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;

@RestController
public class UserController {

    public static final Logger logger = LoggerFactory.getLogger(UserController.class.getName());

    @PostMapping("/add")
    @ResponseBody
    public String add(@Valid User user, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            allErrors.forEach( v ->{
                logger.error(v.getObjectName()+"======"+v.getDefaultMessage());
            });
            return "添加失敗";
        }
        return "添加成功";
    }
}

總結:

瞭解這兩個註解可以讓你的校驗數據更加方便。

到此這篇關於SpringBoot學習篇之@Valid與@Validated區別的文章就介紹到這瞭,更多相關SpringBoot @Valid與@Validated區別內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: