亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java參數(shù)校驗(yàn)@Validated、@Valid介紹及使用詳解

 更新時(shí)間:2024年08月19日 10:41:19   作者:墨鴉_Cormorant  
Javax.validation是?spring?集成自帶的一個(gè)參數(shù)校驗(yàn)接口,可通過添加注解來設(shè)置校驗(yàn)條件,這篇文章主要介紹了Java參數(shù)校驗(yàn)@Validated、@Valid介紹及使用詳解,需要的朋友可以參考下

概述

介紹及使用

描述:Javax.validation是 spring 集成自帶的一個(gè)參數(shù)校驗(yàn)接口。可通過添加注解來設(shè)置校驗(yàn)條件。springboot框架創(chuàng)建web項(xiàng)目后,不需要再添加其他的依賴。

使用:在Controller上使用 @Valid 或 @Validated 注解 開啟校驗(yàn)

public String test(@RequestBody @Valid MyRequest req){};

@Validated 和 @Valid 的異同

相同點(diǎn):

  • 在檢驗(yàn)參數(shù)符合規(guī)范的功能上基本一致;

不同點(diǎn):

  • 提供者不同:
    • validated 是Spring Validation驗(yàn)證框架對(duì)參數(shù)的驗(yàn)證機(jī)制;
    • valid是 javax 提供的參數(shù)驗(yàn)證機(jī)制
  • 作用域不同:
    • validated :類,方法,參數(shù)
    • valid:方法,字段,構(gòu)造方法,參數(shù),TYPE_US

注:TYPE_USE:在 Java 8 之前的版本中,只能允許在聲明式前使用 Annotation。而在 Java 8 版本中,Annotation 可以被用在任何使用 Type 的地方,例如:初始化對(duì)象時(shí) (new),對(duì)象類型轉(zhuǎn)化時(shí),使用 implements 表達(dá)式時(shí),或者使用 throws 表達(dá)式時(shí)。

//初始化對(duì)象時(shí)
String myString = new @Valid String();
//對(duì)象類型轉(zhuǎn)化時(shí)
myString = (@Valid String) str;
//使用 implements 表達(dá)式時(shí)
class MyList<T> implements List<@Valid T> {...}
//使用 throws 表達(dá)式時(shí)
public void validateValues() throws @Valid ValidationFailedException{...}

參數(shù)校驗(yàn)常用注解

除了前四個(gè) @Null,@ NotNull,@ NotBlank,@NotEmpty外,其他所有的注解,傳 null 時(shí)都會(huì)被當(dāng)作有效處理

注解常用參數(shù)值:message(校驗(yàn)不通過反饋信息)

JSR303定義的基礎(chǔ)校驗(yàn)類型:

注解驗(yàn)證的數(shù)據(jù)類型備注
Null任意類型參數(shù)值必須是 Null
NotNull任意類型參數(shù)值必須不是 Null
NotBlank只能作用于字符串字符串不能為 null,而且字符串長(zhǎng)度必須大于0,至少包含一個(gè)非空字符串
NotEmptyCharSequence
Collection
Map
Array
參數(shù)值不能為null,且不能為空
(字符串長(zhǎng)度必須大于0,空字符串(“ ”)可以通過校驗(yàn))
Size(min,max )CharSequence
Collection
Map
Array
字符串:字符串長(zhǎng)度必須在指定的范圍內(nèi)
Collection:集合大小必須在指定的范圍內(nèi)
Map:map的大小必須在指定的范圍內(nèi)
Array:數(shù)組長(zhǎng)度必須在指定的范圍內(nèi)
Pattern(regexp)字符串類型驗(yàn)證字符串是否符合正則表達(dá)式
Min(value)整型類型參數(shù)值必須大于等于 最小值
Max(value)整型類型參數(shù)值必須小于等于 最大值
DecimalMin(value)整型類型參數(shù)值必須大于等于 最小值
DecimalMax(value)整型類型參數(shù)值必須小于等于 最大值
Positive數(shù)字類型參數(shù)值為正數(shù)
PositiveOrZero數(shù)字類型參數(shù)值為正數(shù)或0
Negative數(shù)字類型參數(shù)值為負(fù)數(shù)
NegativeOrZero數(shù)字類型參數(shù)值為負(fù)數(shù)或0
Digits(integer,fraction)數(shù)字類型參數(shù)值為數(shù)字,且最大長(zhǎng)度不超過integer位,整數(shù)部分最高位不超過fraction位
AssertTrue布爾類型參數(shù)值必須為 true
AssertFalse布爾類型參數(shù)值必須為 false
Past時(shí)間類型(Date)參數(shù)值為時(shí)間,且必須小于 當(dāng)前時(shí)間
PastOrPresent時(shí)間類型(Date)參數(shù)值為時(shí)間,且必須小于或等于 當(dāng)前時(shí)間
Future時(shí)間類型(Date)參數(shù)值為時(shí)間,且必須大于 當(dāng)前時(shí)間
FutureOrPresent時(shí)間類型(Date)參數(shù)值為時(shí)間,且必須大于或等于 當(dāng)前日期
Email字符串類型被注釋的元素必須是電子郵箱地址

Hibernate Validator 中附加的 constraint :

注解驗(yàn)證的數(shù)據(jù)類型備注
Length字符串類型字符串的長(zhǎng)度在min 和 max 之間
Range數(shù)字類型
字符串類型
數(shù)值或者字符串的值必須在 min 和 max 指定的范圍內(nèi)

Pattern注解校驗(yàn) 常用正則表達(dá)式

@Pattern(regexp = "^[1-9]]\\d*$", message = "XX參數(shù)值必須是正整數(shù)")

高階使用

自定義分組校驗(yàn)

有時(shí)多個(gè)場(chǎng)景接口公用一個(gè)請(qǐng)求對(duì)象,不同業(yè)務(wù)場(chǎng)景對(duì)請(qǐng)求對(duì)象的參數(shù)校驗(yàn)需求不同,可以使用分組校驗(yàn)來解決

注意:

  • 沒有指定顯示分組的被校驗(yàn)字段和校驗(yàn)注解,默認(rèn)都是 Default 組(即 Default.class)
  • 若自定義的分組接口未繼承 Default 分組,且 @Validated(或 @Valid)注解未傳參 Default.class,則只會(huì)校驗(yàn)請(qǐng)求對(duì)象中進(jìn)行了顯示分組的字段,不會(huì)校驗(yàn)?zāi)J(rèn)分組(沒有進(jìn)行顯示分組)的字段
  • 自定義的分組接口不繼承 Default 分組 + @Validated(或 @Valid)注解傳參 {自定義分組接口.class, Default.class}
  • = 自定義的分組接口繼承 Default 分組 + @Validated(或 @Valid)注解只傳參自定義分組接口

示例:

新建自定義分組校驗(yàn)接口

public interface Student {
}
import javax.validation.groups.Default;
public interface Teacher extends Default {
}

新建請(qǐng)求對(duì)象

@Data
public class UserDTO {
    @NotBlank(message = "不能沒有名稱")
    private String name;
    @NotBlank(message = "老師不能沒有手機(jī)號(hào)", groups = Teacher.class)
    private String phone;
    @NotEmpty(message = "學(xué)生不能沒有書", groups = Student.clas)
    @Size(min = 2, message = "學(xué)生必須有兩本書", groups = Student.class)
    private List<String> bookNames;
}

Controller

@RestController
public class ValidatedController {
    /**
     * 測(cè)試 校驗(yàn)student分組+默認(rèn)分組
     */
    @PostMapping("student")
    public UserDTO validatedStudent(@Validated(value = {Student.class, Default.class}) @RequestBody UserDTO userDTO) {
        return userDTO;
    }
    /**
     * 測(cè)試 校驗(yàn)student分組+默認(rèn)分組
     */
    @PostMapping("teacher")
    public UserDTO validatedTeacher(@Validated(value = {Teacher.class}) @RequestBody UserDTO userDTO) {
        return userDTO;
    }
    /**
     * 測(cè)試 分組校驗(yàn)  default
     */
    @PostMapping("default")
    public UserDTO validatedDefault(@Validated(value = {Default.class}) @RequestBody UserDTO userDTO) {
        return userDTO;
    }
    /**
     * 測(cè)試 分組校驗(yàn) onlyStudent
     */
    @PostMapping("onlyStudent")
    public UserDTO validatedOnlyStudent(@Validated(value = {Student.class}) @RequestBody UserDTO userDTO) {
        return userDTO;
}

自定義校驗(yàn)注解

定義注解

@Documented
//指定注解的處理類
@Constraint(validatedBy = {VersionValidatorHandler.class })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface ConstantVersion {
   String message() default "{constraint.default.const.message}";
   Class<?>[] groups() default {};
   Class<? extends Payload>[] payload() default {};
   String value();
}

注解處理類

public class VersionValidatorHandler implements ConstraintValidator<Constant, String> {
    private String constant;
    @Override
    public void initialize(Constant constraintAnnotation) {
        //獲取設(shè)置的字段值
        this.constant = constraintAnnotation.value();
    }
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        //判斷參數(shù)是否等于設(shè)置的字段值,返回結(jié)果
        return constant.equals(value);
    }
}

自定義注解使用

@ConstantVersion (message = "verson只能為1.0.0",value="1.0.0")
String version;

Controller

@RestController
public class TestController {
    @RequestMapping("/test")
    public String createUser(@Valid User user, BindingResult bindingResult){
        if (bindingResult.hasErrors()){
            return bindingResult.getFieldError().getDefaultMessage();
        }
        return  "success";
    }
}

嵌套檢驗(yàn)

描述:當(dāng)對(duì)象 Man 的字段 houses 包含 House 對(duì)象類型時(shí),在檢驗(yàn) houses 字段時(shí)可以檢驗(yàn) House 對(duì)象的屬性字段時(shí),就稱為嵌套檢驗(yàn)

方案:在被檢驗(yàn)的字段上添加 @Valid 注解就可以實(shí)現(xiàn)嵌套檢驗(yàn)

示例如下:

  • 在檢驗(yàn) Man 對(duì)象的 houses 字段時(shí),在houses 字段上添加 @Valid 注解后,就可以檢驗(yàn) list 中的 House 的屬性是否符合要求;
  • 否則只會(huì)檢驗(yàn) houses 的集合大小是否大于1,不會(huì)校驗(yàn)集合中的 House 對(duì)象,比如 House 對(duì)象的 name 長(zhǎng)度是否符合要求。
class Man{
    @Valid
    @Size(min = 1)
    private List<House> houses;
}
class House{
    @Length(min = 1,max = 10)
    private String name;
}

拓展

異常處理

參數(shù)校驗(yàn)異常:MethodArgumentNotValidException

方式一:基于異常監(jiān)聽@ControllerAdvice(參考:https://www.cnblogs.com/gezi0815/p/13815397.html)

/**
* 全局異常處理器
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 異常處理
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public DataResult exceptionHandler(Exception e) {
        log.error("GlobalExceptionHandler.exceptionHandler , 異常信息",e);
        return DataResult.fail(e.getMessage());
    }
    /**
     * 業(yè)務(wù)異常
     */
    @ResponseBody
    @ExceptionHandler(value = BplCommonException.class)
    public DataResult bplCommonExceptionHandler(BplCommonException e) {
        log.warn("",e);
        return DataResult.fail(e.getMessage());
    }
    /**
     * 處理所有RequestBody注解參數(shù)驗(yàn)證異常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public DataResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
        log.warn(e.getMessage());
        return DataResult.fail(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
    }
    /**
     * 處理所有RequestParam注解數(shù)據(jù)驗(yàn)證異常
     */
    @ExceptionHandler(BindException.class)
    public DataResult handleBindException(BindException ex) {
        FieldError fieldError = ex.getBindingResult().getFieldError();
        log.warn("必填校驗(yàn)異常:{}({})", fieldError.getDefaultMessage(),fieldError.getField());
        return DataResult.fail(ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
    }
}

方式二:基于Handle或Filter(參考:https://blog.51cto.com/u_12012821/2511625)

if (e instanceof MethodArgumentNotValidException) {
	String errorMsg = ((MethodArgumentNotValidException) e)
		.getBindingResult()
		.getAllErrors()
        .stream()
		.map(DefaultMessageSourceResolvable::getDefaultMessage)
		.collect(Collectors.joining(","));
	resp = R.builder()
		.code(ResultCodeEnum.BUSINESS_ERROR.getCode())
		.message(errorMsg).success(false)
		.build();
} 

到此這篇關(guān)于Java參數(shù)校驗(yàn)@Validated、@Valid使用詳解的文章就介紹到這了,更多相關(guān)java參數(shù)校驗(yàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring boot mogodb多條件拼接的解決方法

    spring boot mogodb多條件拼接的解決方法

    這篇文章主要介紹了spring boot mogodb多條件拼接的解決方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-08-08
  • Netty分布式固定長(zhǎng)度解碼器實(shí)現(xiàn)原理剖析

    Netty分布式固定長(zhǎng)度解碼器實(shí)現(xiàn)原理剖析

    這篇文章主要為大家介紹了Netty分布式固定長(zhǎng)度解碼器原理剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • 如何避免Apache?Beanutils屬性copy

    如何避免Apache?Beanutils屬性copy

    這篇文章主要為大家介紹了如何避免Apache?Beanutils屬性copy的分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • java中使用zxing批量生成二維碼立牌

    java中使用zxing批量生成二維碼立牌

    本篇文章主要介紹了java中使用zxing批量生成二維碼立牌,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。
    2016-12-12
  • SpringBoot啟動(dòng)時(shí)如何通過啟動(dòng)參數(shù)指定logback的位置

    SpringBoot啟動(dòng)時(shí)如何通過啟動(dòng)參數(shù)指定logback的位置

    這篇文章主要介紹了SpringBoot啟動(dòng)時(shí)如何通過啟動(dòng)參數(shù)指定logback的位置,在spring boot中,使用logback配置的方式常用的有兩種,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • JAVA如何定義構(gòu)造函數(shù)過程解析

    JAVA如何定義構(gòu)造函數(shù)過程解析

    這篇文章主要介紹了JAVA如何定義構(gòu)造函數(shù)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Spring Boot集成MinIO對(duì)象存儲(chǔ)服務(wù)器操作步驟

    Spring Boot集成MinIO對(duì)象存儲(chǔ)服務(wù)器操作步驟

    通過Spring Boot集成MinIO,你可以在應(yīng)用中方便地進(jìn)行文件的存儲(chǔ)和管理,本文給大家分享Spring Boot集成MinIO對(duì)象存儲(chǔ)服務(wù)器詳細(xì)操作步驟,感興趣的朋友一起看看吧
    2024-01-01
  • 詳解Java中的ThreadLocal

    詳解Java中的ThreadLocal

    ThreadLocal是JDK包提供的,它提供線程本地變量,如果創(chuàng)建一個(gè)ThreadLocal變量,那么訪問這個(gè)變量的每個(gè)線程都會(huì)有這個(gè)變量的一個(gè)副本,在實(shí)際多線程操作的時(shí)候,操作的是自己本地內(nèi)存中的變量,從而規(guī)避了線程安全問題
    2021-06-06
  • java中Path和ClassPath用法比較

    java中Path和ClassPath用法比較

    在本篇文章里小編給大家分享了關(guān)于java中Path和ClassPath用法比較內(nèi)容,有需要的朋友們學(xué)習(xí)下。
    2019-01-01
  • Maven安裝及MyEclipse中使用Maven

    Maven安裝及MyEclipse中使用Maven

    這篇文章主要為大家詳細(xì)介紹了Maven安裝步驟,及MyEclipse中如何使用Maven,感興趣的小伙伴們可以參考一下
    2016-07-07

最新評(píng)論