当前位置 : 主页 > 编程语言 > java >

Validated

来源:互联网 收集:自由互联 发布时间:2023-03-22
@Validated、@Valid等注解用法详解 1.情景展示 SpringBoot,SpringMvc 常用参数校验用法详解 在实际开发过程中,针对前端请求参数的校验是一个不小的工作量。 什么时候需要对请求参数进行校

@Validated、@Valid等注解用法详解

1.情景展示

SpringBoot,SpringMvc 常用参数校验用法详解

在实际开发过程中,针对前端请求参数的校验是一个不小的工作量。

什么时候需要对请求参数进行校验?

情形1:前后端分离

前后端分离,虽然会提高项目的开发进度,但同样也存在前后端开发人员交流不及时等问题。

比方说:性别参数,后端要求只能传1或2,前端非要给你传男或女,当前后端对于数据的要求标准不一致时,就会出现问题。

后台对入参进行校验,一方面,可以提高数据的规范性;另一方面,也可以增加数据的安全性(比如:数据在传输过程中被篡改)。

情形2:对外提供接口

本质上,前后端分离,后台提供请求,也是属于接口,这里特指的是后台对后台。

也就是说,别的项目或者公司需要调用咱们写的接口,这个时候,参数的校验就显得格外重要,不想前后端那种,后台加不加校验都没有太大的影响。

2.准备工作

关于校验标准,可供java使用的一共有两套:

  一种是:Java API规范 (JSR303) 定义了Bean校验的标准validation-api,但没有提供实现。

  另一种是:hibernate validation是对这个规范的实现,并增加了校验注解如@Email、@Length等。

  Spring Validation是对hibernate validation的二次封装,用于支持spring mvc参数自动校验。

  接下来,我们以spring-boot项目为例,介绍Spring Validation的使用。

关于jar包的引用

  如果spring-boot版本小于2.3.x,spring-boot-starter-web会自动传入hibernate-validator依赖;

  如果spring-boot版本大于2.3.x,则需要手动引入依赖:

<!--spring对参数进行校验:hibernate validator--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.18.Final</version> </dependency>

现在网络上都是旧的内容,用的是:

Validated_java

完全没有必要,使用第一个jar包就可以了。

关于jar包的区别,文末会进行详细解说。

@Valid和@Validated的区别

Validated_@Validated_02

3.具体实现

用法1:requestParam参数校验

描述:通常用于get请求或者请求参数比较少的情形。

校验生效的前提:

必须在Controller类上标注@Validated注解,在方法或者参数前添加无效!

Validated_spring_03

如果校验失败,会抛出ConstraintViolationException异常。

用法:

将请求入参一一在请求方法()内,进行罗列,并将校验注解添加在对应入参的前面。

Validated_@Validated_04

2022年2月19日17:17:31

@RequestParam注解的required属性的默认值为true,也就是,要求该参数是必传项;

如果可以为空的话,需要将其值改成false:

Validated_java_05

另外,如果请求参数与自己定义的接收的变量名称不一样的话,可以进行映射;

即:只要@RequestParam里面的名称和请求入参名称保持一致即可。

Validated_@Valid_06

我们可以看到,只要对照好参数映射关系,就能接收到数据。

用法2:pathVariable参数校验

描述:通过{}来动态配置请求路径,并将请求路径当成方法的入参之一。

校验生效的前提:

必须在Controller类上标注@Validated注解,在方法或者参数前添加无效!

如果校验失败,会抛出ConstraintViolationException异常。

用法:校验注解可以放在@PathVariable前面也可以放在它的后面。

Validated_@Validated_07

用法3:responseBody参数校验(application/json)

当请求方法入参有@RequestBody注解的时候,spring会将它识别成JSON格式的请求,要求调用方必须发送application/json格式的数据;

第1步:在实体类的字段上加上约束注解;

Validated_@Valid_08

第2步:在方法参数上声明校验注解。

格式:@RequestBody+@Validated+实体类

或者:@RequestBody+@Valid+实体类

Validated_@Valid_09

这种情况下,使用@Valid和@Validated都可以(只能用@Valid或@Validated的地方,下面会讲)。

用法4:responseBody参数校验(application/x-www-form-urlencoded)

当请求方法入参只有实体类接收的时候,spring会将它识别成FORM表单请求,要求调用方必须发送application/x-www-form-urlencoded格式的数据;

第1步:在实体类的字段上加上约束注解;

Validated_@Valid_10

第2步:在方法参数上声明校验注解。

Validated_java_11

同样地,使用@Valid和@Validated都可以。

4.参数校验配置

Spring Validation默认会校验完所有字段,然后才抛出异常。可以通过一些简单的配置,开启Fali Fast模式,一旦校验失败就立即返回。

查看代码

import org.hibernate.validator.HibernateValidator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; / * 请求参数校验配置 * @description: * @author: Marydon * @date: 2020-08-10 14:57 * @version: 1.0 * @email: marydon20170307@163.com */ @Configuration public class WebParamValidateConfig { @Bean public Validator validator() { ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class) .configure() //failFast的意思只要出现校验失败的情况,就立即结束校验,不再进行后续的校验。 .failFast(true) .buildValidatorFactory(); return validatorFactory.getValidator(); } @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor(); methodValidationPostProcessor.setValidator(validator()); return methodValidationPostProcessor; } }

5.统一异常处理

如果校验失败,会抛出异常,我们需要对异常进行管理,以便返回一个更友好的提示。

下面是我总结的异常拦截配置类:

查看代码

import org.jetbrains.annotations.NotNull; import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.validation.BindException; import org.springframework.web.HttpMediaTypeNotSupportedException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import java.util.stream.Collectors; / * 全局异常处理器 * @description: @ControllerAdvice默认会对所有的请求进行处理; * 对请求入参的校验异常,根本进不到Controller的方法体内,所以,只能在这拦截异常后返回友好错误提示 * 加basePackages,可以只对具体包名下面的请求进行处理 * @ControllerAdvice是一个增强的 Controller。使用这个 Controller,可以实现三个方面的功能: * 全局异常处理 * 全局数据绑定 * 全局数据预处理 * 只拦截Controller,不会拦截Interceptor的异常 * @author: Marydon * @date: 2020年08月10日 0010 16:39 / // 异常拦截位置 @RestControllerAdvice(basePackages = {"com.xx" ,"com.yy"}) public class CzWebExceptionHandler { //处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常,详情继续往下看代码 @ExceptionHandler(BindException.class) public CzResponseDto<JSONObject> BindExceptionHandler(@NotNull BindException e) { String errorMsg = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining()); return CzResult.error("接口调取失败:" + errorMsg, null); } //处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException @ExceptionHandler(ConstraintViolationException.class) public CzResponseDto<JSONObject> ConstraintViolationExceptionHandler(@NotNull ConstraintViolationException e) { String errorMsg = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining()); return CzResult.error("接口调取失败:" + errorMsg, null); } //处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。 @ExceptionHandler(MethodArgumentNotValidException.class) public CzResponseDto<JSONObject> MethodArgumentNotValidExceptionHandler(@NotNull MethodArgumentNotValidException e) { String errorMsg = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining()); return CzResult.error("接口调取失败:" + errorMsg, null); } // 要求Content-type为application/json,但是内容类型却是text/plain或者text时会被该异常捕获 @ExceptionHandler(HttpMediaTypeNotSupportedException.class) public CzResponseDto<JSONObject> HttpMediaTypeNotSupportedExceptionHandler(@NotNull HttpMediaTypeNotSupportedException e) { String errorMsg = "本接口不接收application/json以外格式的数据,请检查入参是否是标准的json数据!\n" + e.getMessage(); return CzResult.error("接口调取失败:" + errorMsg, null); } @ExceptionHandler(Exception.class) public CzResponseDto<JSONObject> handleException(@NotNull Exception e) { String errorMsg = "系统异常,请联系开发人员Marydon进行排错!\n" + e.getMessage(); return CzResult.error("接口调取失败:" + errorMsg, null); } // 运行异常 @ExceptionHandler(RuntimeException.class) public CzResponseDto<JSONObject> handleRuntimeException(@NotNull Exception e) { return CzResult.error("接口调取失败:" + e.getMessage(), null); } // 服务异常 @ExceptionHandler(ServiceException.class) public CzResponseDto<JSONObject> handleServiceException(@NotNull Exception e) { return CzResult.error("接口调取失败:" + e.getMessage(), null); } // 请求方式异常(仅支持post请求) @ExceptionHandler(HttpRequestMethodNotSupportedException.class) public CzResponseDto<JSONObject> handleHttpRequestMethodNotSupportedException(@NotNull Exception e) { return CzResult.error("接口调取失败:" + e.getMessage(), null); } // 不存在的请求方法InterfaceMethod,在CzRequestParams可以查看支持的接口 // 注意:当请求数据格式为非text或text/plain时,也会抛出该异常(application/javascript,application/xml,text/xml,text/html) // 无请求入参时也会抛出该异常 @ExceptionHandler(HttpMessageNotReadableException.class) public CzResponseDto<JSONObject> handleHttpMessageNotReadableException(@NotNull Exception e) { // return CzResult.error("接口调取失败:未知的接口方法,请仔细核对入参InterfaceMethod的值!", null); return CzResult.error("接口调取失败:" + e.getMessage(), null); } }

仅供参考。

6.常用注解

JSR标准注解

约束注解

支持的类型

说明

@AssertFalse

Boolean,boolean

元素值必须是false

@AssertTrue

Boolean,boolean

元素值必须是true

@DecimalMax

BigDecimal,BigInteger, byte,short, int, long,等任何Number或CharSequence(存储的是数字)

value:数值上限 inclusive:是否包含此上限,默认true是包含的

@DecimalMin

同上

不解释

@Max

同上

值=max,也是校验通过的

@Min

同上

不解释

@Digits

同上

integer:整数位数上限 fraction:小数位数上限

@Positive

同上

2.0。必须是严格的正数。0都不行~

@PositiveOrZero

同上

2.0。 0是被允许的

@Negative

同上

2.0。 必须是严格的负数。0都不行

@NegativeOrZero

同上

2.0。 0是被允许的

@Email

CharSequence子类型(如String)

2.0。值是否是Email,也可以通过​​regexp​​​和​​flag​​指定自定义的email格式

@Future

Date、Calendar及所有JSR 310时间类

是否是将来时间(若是这种​​LocalTime.now()​​取当前的,都会是false哦~)

@FutureOrPresent

同上

2.0。和上面的区别是now也行~

@Past

同上

不解释

@PastOrPresent

同上

2.0。不解释

@NotBlank

CharSequence子类型(如String)

2.0。规则为​​.trim().length() > 0​​​(注意:​​null is not valid​​)

@NotEmpty

CharSequence子类型、Collection、Map、数组

2.0。长度/size大小>0(注意:​​null is not valid​​)

@Size

CharSequence子类型、Collection、Map、数组

2.0。min:最小值 max:最大值。(注意:边界值是包含的。null is valid哦~~)

@NotNull

所有类型

不解释

@Null

所有类型

不解释

@Pattern

CharSequence子类型(如String)

是否满足此正则表达式。regexp:正则。flags:模式

​​@Valid​​

非原子类型

级联属性校验

说明:

  • ​​@DecimalMax​​​和​​@Max​​的区别:
  • ​​@DecimalMax​​支持类型:Number、BidDecimal、Float、Double、BigInteger、Long
  • ​​@Max​​支持的类型:同上
  • 它俩都还能标注在String上,比如“6”这种字符串。(若你不是数字字符串,永远校验不通过)
  • 所有没有特殊说明的:​​null is valid​​
  • 若在不支持的类型上使用约束注解,运行时抛出异常:​​javax.validation.UnexpectedTypeException​​:No validator could be found for constraint ‘javax.validation.constraints.Future’ validating type ‘java.lang.String’
  • ​​@FutureOrPresent​​​和​​@PastOrPresent​​​这块注意:对于​​Present​​​的匹配,要注意程序是有执行时间的。so如果是匹配时间戳​​Instant​​​,若是​​Instant.now()​​​的话,​​@FutureOrPresent​​​就是非法的,而​​@PastOrPresent​​​就成合法的了。但是若是日期的话比如​​LocalDate.now()​​就不会有这问题,毕竟你的程序不可能执行一天嘛~~~~
  • @Length:校验字符串长度;
  • @Size:校验数组、集合大小(java,经测试无效);
  • @NotBlank:只用在String上,表示:传进来的值不能为null,而且调用trim()后,长度必须大于0,即:必须有实际字符;
  • @NotEmpty:不能为null,而且长度必须大于0,只能校验字符串;
  • ​​@NotNull​​:不能为null,但值可以为empty(分配了内存空间),只能校验String类型和对象;有的人问用在基本类型(非包装类型报错吗?),很显然不会报错。因为基本类型都有默认值,不可能为null的
  • @Pattern:正则表达式校验(只能用于校验字符串,即String类型,不能定义成Integer或Long类型,否则报错),使用标准的正则表达式用法,带反斜杠\的会自动转义。
  • 所有的注解都能标注在:字段、方法、构造器、入参、以及注解上
  • Validated_@Valid_12

    ​​JSR​​​的注解都申明都非常的简单,没有Hibernate提供的复杂,比如没有用到​​@ReportAsSingleViolation​​等注解内容~为了方面,下面列出各个注解的默认提示消息(中文):

    javax.validation.constraints.AssertFalse.message = 只能为falsejavax.validation.constraints.AssertTrue.message = 只能为truejavax.validation.constraints.DecimalMax.message = 必须小于或等于{ value}javax.validation.constraints.DecimalMin.message = 必须大于或等于{ value}javax.validation.constraints.Digits.message = 数字的值超出了允许范围(只允许在{ integer}位整数和{ fraction}位小数范围内)javax.validation.constraints.Email.message = 不是一个合法的电子邮件地址javax.validation.constraints.Future.message = 需要是一个将来的时间javax.validation.constraints.FutureOrPresent.message = 需要是一个将来或现在的时间javax.validation.constraints.Max.message = 最大不能超过{ value}javax.validation.constraints.Min.message = 最小不能小于{ value}javax.validation.constraints.Negative.message = 必须是负数javax.validation.constraints.NegativeOrZero.message = 必须是负数或零javax.validation.constraints.NotBlank.message = 不能为空javax.validation.constraints.NotEmpty.message = 不能为空javax.validation.constraints.NotNull.message = 不能为nulljavax.validation.constraints.Null.message = 必须为nulljavax.validation.constraints.Past.message = 需要是一个过去的时间javax.validation.constraints.PastOrPresent.message = 需要是一个过去或现在的时间javax.validation.constraints.Pattern.message = 需要匹配正则表达式"{regexp}"javax.validation.constraints.Positive.message = 必须是正数javax.validation.constraints.PositiveOrZero.message = 必须是正数或零javax.validation.constraints.Size.message = 个数必须在{ min}和{ max}之间

    参考文件​​ValidationMessages_zh_CN.properties​​,若消息不适合你,可自行定制~

    Hibernate Validation扩展的注解

    约束注解

    支持的类型

    说明

    @URL

    CharSequence

    校验URL。protocol=””,host=””, port=””, regexp=”.*”, flags={}

    @UniqueElements

    Collection

    集合内不允许有重复元素。

    @SafeHtml

    CharSequence

    传入的文本中不能含有​​script​​​等敏感标签。(注意:需要​​org.jsoup​​包的支持)

    @Range

    同​​@Min​​

    是对​​@Min​​​和​​@Max​​的结合补充

    @Length

    CharSequence

    ​​value.length() >= min && value.length() <= max​​(null is valid)

    @ISBN

    CharSequence

    校验图书的ISBN。​​type:Type.ISBN_13​​(还有个取值:ISBN_10)

    @EAN

    CharSequence

    校验商用条形码​​EAN​​

    @Currency

    MonetaryAmount

    校验货币。value:只允许的货币种类,如​​USD, EUR​​等

    @CodePointLength

    CharSequence

    校验代码点​​codePoint​​​。关于String的length和代码点,可​​参考这里​​​ 一般不使用,使用​​@Length​​即可~

    @ConstraintComposition

    all

    所有约束是AND/OR/ALL_FALSE关系。它只能标注在注解上,运用于组合注解上

    ​​@DurationMax​​

    Duration

    ​​maxDuration.compareTo( value )​​这么比较的,相等也是valid的

    ​​@DurationMin​​

    Duration

    `minDuration.compareTo( value )这么比较的,相等也是valid的

    @CNPJ

    CharSequence

    法人国家登记号

    说明:

  • ​​@ReportAsSingleViolation​​​:如果​​@NotEmpty​​​、​​@Pattern​​都校验失败,不添加此注解,则会生成两个校验失败的结果。若添加了此注解,那错误消息以它标注的本注解的​​message​​为准
  • 所有没有特殊说明的:​​null is valid​​。
  • 所有约束注解都可重复标注
  • 各个注解的默认提示消息(中文):

    org.hibernate.validator.constraints.CreditCardNumber.message = 不合法的信用卡号码org.hibernate.validator.constraints.Currency.message = 不合法的货币 (必须是{ value}其中之一)org.hibernate.validator.constraints.EAN.message = 不合法的{ type}条形码org.hibernate.validator.constraints.Email.message = 不是一个合法的电子邮件地址org.hibernate.validator.constraints.Length.message = 长度需要在{ min}和{ max}之间org.hibernate.validator.constraints.CodePointLength.message = 长度需要在{ min}和{ max}之间org.hibernate.validator.constraints.LuhnCheck.message = ${ validatedValue}的校验码不合法, Luhn模10校验和不匹配org.hibernate.validator.constraints.Mod10Check.message = ${ validatedValue}的校验码不合法, 模10校验和不匹配org.hibernate.validator.constraints.Mod11Check.message = ${ validatedValue}的校验码不合法, 模11校验和不匹配org.hibernate.validator.constraints.ModCheck.message = ${ validatedValue}的校验码不合法, ${ modType}校验和不匹配org.hibernate.validator.constraints.NotBlank.message = 不能为空org.hibernate.validator.constraints.NotEmpty.message = 不能为空org.hibernate.validator.constraints.ParametersScriptAssert.message = 执行脚本表达式"{script}"没有返回期望结果org.hibernate.validator.constraints.Range.message = 需要在{ min}和{ max}之间org.hibernate.validator.constraints.SafeHtml.message = 可能有不安全的HTML内容org.hibernate.validator.constraints.ScriptAssert.message = 执行脚本表达式"{script}"没有返回期望结果org.hibernate.validator.constraints.URL.message = 需要是一个合法的URL

    此处用到了​​${validatedValue}​​​、​​${modType}​​​是EL表达式的语法。​​​@DurationMax​​​和​​@DurationMin​​的message消息此处未贴出,有大量的EL计算,太长了~~~

    自定义注解

    定义注解

    import cn.lucky.common.annotation.validation.ValidatorImpl.PhoneValidatorImpl;import javax.validation.Constraint;import javax.validation.Payload;import java.lang.annotation.*;@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@Documented// 校验逻辑类@Constraint(validatedBy = PhoneValidatorImpl.class)/** * phone 校验注解 * @author lucky**/public @interface IsPhone { String message() default "手机号不正确"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { };}

    添加校验逻辑实现类 PhoneValidatorImpl

    import cn.hutool.core.util.PhoneUtil;import cn.lucky.common.annotation.validation.IsPhone;import javax.validation.ConstraintValidator;import javax.validation.ConstraintValidatorContext;/** * @author lucky */public class PhoneValidatorImpl implements ConstraintValidator<IsPhone,String> { @Override public boolean isValid(String phone, ConstraintValidatorContext constraintValidatorContext) { // 这里使用了hutool工具类,读者也可自信实现具体逻辑 return PhoneUtil.isMobile(phone); }}

    使用

    public class RegistryBO { /** * 用户名 **/ @IsPhone private String username; /** * 密码 **/ private String password;}/** * @author lucky */@RestController@RequestMapping("/publisher/write")public class Publisher { @Autowired private PublisherService publisherService; /** * 注册发布者 * @param registryBO registryBO * @return BaseResponse **/ @PostMapping("/registry") public BaseResponse registry(@RequestBody @Valid RegistryBO registryBO) { boolean registry = publisherService.registry(registryBO); return registry ? BaseResponse.success() : BaseResponse.error(); }}

    5.扩展延伸

    延伸1:分组校验

    在实际项目中,可能多个方法需要使用同一个实体类来接收参数,而不同方法的校验规则很可能是不一样的;

    这个时候,简单地在实体的字段上加约束注解无法解决这个问题。

    因此,spring-validation支持了分组校验的功能,专门用来解决这类问题。

    举个栗子:

    A方法要求参数1的值必须为1,B方法则要求其值必须为2,如何实现?

    第1步:在实体类当中添加接口类;

    把接口类用作分组的依据;

    注意:在实体类当中添加的接口,没有实际意义,仅仅将其作为分组依据;

    由于spring校验的groups只能这样用,没有办法。

    Validated_@Valid_13

    第1步:在约束注解里,添加该注解生效的的分组信息groups。

    多个组之间使用逗号隔开;

    并且,组必须以".class"进行结尾。

    Validated_spring_14

    针对不同的组,可以添加不同的校验规则。

    第2步:@Validated注解上指定校验分组。

    Validated_@Validated_15

    注意:分组校验只能使用注解@Validated,不能使用@Valid!

    另外,方法上使用了分组校验,实体类需要多组共用的字段规则校验,也必须添加组,即使是:校验规则一致的。

    Validated_@Validated_16

    否则的话,该校验规则将会失效。

    延伸2:嵌套校验

    当入参实体类的某字段也是对象时,这时,需要对该对象里的字段进行校验时,这就牵扯到了:嵌套校验;

    此时,入参实体类的对应的字段对象,必须标记@Valid注解。

    Validated_spring_17

    嵌套的实体类,示例:

    Validated_spring_18

    延伸3:集合校验(list)

    如果请求体直接传递了json数组给后台,并希望对数组中的每一项都进行参数校验。

    此时,如果我们直接使用java.util.Collection下的list或者set来接收数据,参数校验并不会生效!

    我们可以使用自定义list集合来接收参数:

    第1步:包装List类型,并声明@Valid注解;

    查看代码

    public class ValidationList<E> implements List<E> { @Delegate @Valid public List<E> list = new ArrayList<>(); @Override public String toString() { return list.toString(); } }

    @Delegate注解受lombok版本限制,1.18.6以上版本可支持;

    如果校验不通过,会抛出NotReadablePropertyException,同样可以使用统一异常进行处理。

    第2步:校验调用

    格式:@Validated + ValidationList&lt;实体类。

    比如,我们需要一次性保存多个User对象,Controller层的方法可以这么写:

    查看代码

    @PostMapping("/saveList") public Result saveList(@RequestBody @Validated(UserDTO.Save.class) ValidationList<UserDTO> userList) { return Result.ok(); }

    说明:后端如果想要使用list接收数据的话,必须加上注解@RequestBody;

    前端必须发送json请求:application/json,也就说前端的参数格式为:JsonArray。

    延伸4:自定义校验

    延伸5:编程式校验

    2022年1月20日10:52:04

    6.hibernate-validator.jar详细介绍

    当spring-boot-starter-web.jar的版本为1.X时,该jar包依赖的有:hibernate-validator.jar;

    hibernate-validator.jar又依赖了:validation-api.jar。

    Validated_@Validated_19

    当spring-boot-starter-web.jar的版本为2.X时,该jar包没有依赖hibernate-validator.jar,也没有依赖:validation-api.jar;

    Validated_@Valid_20

    此时只能使用注解@Validated

    Validated_@Valid_21

    但是,只有它的话,并不能完成参数的校验。

    我们由开篇了解到:参数校验,要么用hibernate校验,要么使用java校验。

    hibernate-validator.jar包的引入有两种方式:

    方式一:org.hibernate.validator

    <!--spring对参数进行校验:hibernate validator--> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.18.Final</version> </dependency>

    Validated_java_22

    方式二:org.hibernate

    <!--spring对参数进行校验:hibernate validator--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.8.Final</version> </dependency>

    Validated_@Valid_23

    我们可以看到:这两种方式引入的hibernate-validator.jar都对jakarta.validation-api.jar有依赖;

    因此,无需额外引入依赖:

    <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency>

    小结:

    当spring-boot-starter-web.jar的版本为1.X时,该jar包依赖的有:hibernate-validator.jar,无需额外引入;

    当spring-boot-starter-web.jar的版本为2.X时,该jar包需要引入依赖:hibernate-validator.jar(以上两种引入方式均可)。

    上一篇:TCP 三次握手,给我长脸了噢
    下一篇:没有了
    网友评论