SpringBoot使用注解实现参数校验

电玩女神 2024-02-17 12:35 135阅读 0赞

文章目录

  • 参数校验
    • - Validation
    • - Hibernate Validator
  • 校验注解
    • 注解通用属性
    • - Validator 内置注解
    • - Hibernate Validator 附加注解
  • 校验开启
    • @Valid和@Validated
  • 校验分类
    • - Controller校验
    • - Spring Bean校验
  • 校验使用
    • - Controller:参数对象校验
    • - Spring Bean:方法返回值对象校验
    • - Spring Bean:方法参数对象校验
    • 分组校验
      • - Controller:方法参数分组校验
    • 嵌套校验
      • - Controller:方法参数嵌套校验
      • - Spring Bean:方法返回值嵌套校验
      • - Spring Bean:方法参数嵌套校验
  • 自定义注解

参数校验

Spring Boot框架默认使用Hibernate Validator作为校验器实现。参数校验使用JSR-303规范定义的校验注解来实现的。

实际上,在Spring项目中,参数校验并仅支持用在Controller层上面,其实是支持用在所有的Spring Bean上(Controller、Service、Repository等)。

配置依赖:

  1. SpringMVC项目:

    1. <dependency>
    2. <groupId>org.hibernate.validator</groupId>
    3. <artifactId>hibernate-validator</artifactId>
    4. <version>6.0.18.Final</version>
    5. </dependency>
  2. SpringBoot项目:

    1. <dependency>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-web</artifactId>
    4. </dependency>

- Validation

javax.validation 并不是 JDK 的一部分,它是 Java EE 的一部分,它提供了基于注释和 API 的对象校验功能,即 JSR 303 规范。JSR 303 规范定义了一套用于在 JavaBean 中定义验证约束的元数据模型并提供用于编程方式和声明式验证的 API。

  • 在 JavaEE6 中,这个规范被定义为 JSR 303
  • 在 JavaEE7 中则成为了 JSR 349
  • 在 JavaEE8 中成为 JSR 380

javax.validation 包中包含了很多注解,如@NotNull、@Size、@Pattern,它们可以用来对 JavaBean 中的属性进行各种验证,以保证数据的有效性和安全性。

需要注意的是,虽然 JSR-303 规范是 Java EE 的一部分,但我们仍然可以在非 Java EE 的应用程序中使用它,例如 Spring Boot、Spring MVC 等。在使用时需要导入 javax.validation 的 jar 包或者其他支持JSR 303规范的第三方库。

- Hibernate Validator

hibernate-validator是一个流行的Java数据校验器库,它基于JSR 303规范实现了Bean Validation 2.0 API,并提供了许多常用的校验注解和校验器。

校验注解

注解通用属性

  • message:错误提示信息

    可以使用 {} 占位符来引用注解中的属性值或自定义的文本。可以在错误消息中动态地插入变量的值,使错误消息更具体和有意义。

    使用方式:

    • 自定义文本

      1. @Size(min = 5, max = 10, message = "用户名长度不正确")
      2. private String username;
    • 引用注解中的属性值

      1. @Size(min = 5, max = 10, message = "用户名长度必须介于 {min} 到 {max} 之间")
      2. private String username;
    • 引用配置文件配置参数的值

      1. @Size(min = 5, max = 10, message = "{javax.validation.constraints.Size.message}")
      2. private String username;

      为了提供国际化和本地化支持,错误消息通常会使用特定的键(key)来标识。这些键将在校验过程中与消息资源包(message bundle)中的实际错误消息文本进行映射。

  • groups:所属的校验组

    校验组是一种逻辑分组,可以根据不同的场景或需求对校验规则进行分组。默认情况下,参数校验不属于任何校验组,即属于默认组(Default)。

  • payload:携带额外的信息负载

    这些信息负载可以在校验失败时获得。通常情况下,我们不需要使用该属性。

- Validator 内置注解

























































































































注解 注解的其它属性 注解描述
@Null 验证对象是否为 null
@NotNull 验证对象不为 null
@NotBlank 验证字符串不为空,去除前后空格后长度大于 0
@NotEmpty 验证对象不为 null 且不为空(如字符串、集合、数组等),去除前后空格后长度大于 0
@Size min:最小值
max:最大值
验证对象(字符串、集合、数组等)长度在 min 和 max 之间
@Max value:最大值 验证数值(byte、short、int、long 等)是否小于等于指定的最大值
@Min value:最小值 验证数值(byte、short、int、long 等)是否大于等于指定的最小值
@DecimalMax value:最大值
inclusive:是否包含边界
验证 BigDecimal 和 BigInteger 的值是否小于等于指定的最大值
@DecimalMin value:最小值
inclusive:是否包含边界
验证 BigDecimal 和 BigInteger 的值是否大于等于指定的最小值
@Digits integer:整数位数
fraction:小数位数
验证数值是否符合整数位数和小数位数要求
@Pattern regexp:正则表达式 验证字符串是否符合指定的正则表达式
@Email 验证字符串是否符合 Email 格式
@Future 验证日期是否为将来某个时间
@FutureOrPresent 验证日期是否为将来某个时间或当前时间
@Past 验证日期是否为过去某个时间
@PastOrPresent 验证日期是否为过去某个时间或当前时间
@AssertTrue 验证 boolean 类型是否为 true
@AssertFalse 验证 boolean 类型是否为 false
@Positive 验证数值是否为正数
@PositiveOrZero 验证数值是否为正数或零
@Negative 验证数值是否为负数
@NegativeOrZero 验证数值是否为负数或零

@Max(value)、@Min(value)、@DecimalMax(value)、@DecimalMin(Value)区别:

  • @Max、@Min接受一个Long类型的值
  • @DecimalMax、@DecimalMin接受一个字符串类型的值(BigDecimal的字符串表示形式,因此可以是小数)
  • 数字超过Long.MAX_VALUE或Long.MIN_VALUE以下或者数字是小数,@DecimalMax、@DecimalMin是唯一的选择。

- Hibernate Validator 附加注解






















































































注解 注解的其它属性 注解描述
@Length min:最小长度
max:最大长度
验证字符串的长度是否在指定范围内
@Range min:最小值
max:最大值
验证数字(BigDecimal, BigInteger, String, byte, short, int, long和原始类型的包装类 )是否在指定范围内
@UniqueElements 验证集合中的元素是否唯一
@URL protocol:协议
host:主机
port:端口
regexp:正则表达式
flags:标志
验证字符串是否符合 URL 格式要求
@Hexadecimal 验证字符串是否是十六进制的格式
@ISBN type:ISBN类型 验证字符串是否是有效的ISBN码
@CreditCardNumber ignoreNonDigitCharacters:是否忽略非数字字符 验证字符串是否是有效的信用卡号码
@Currency value:货币代码 验证字符串是否是有效的货币代码
@CodePointLength min:最小码点长度
max:最大码点长度
验证字符串的码点长度是否在指定范围内
@Mod10Check 验证字符串是否通过Mod 10算法校验
@Mod11Check 验证字符串是否通过Mod 11算法校验
@LuhnCheck 验证字符串是否通过Luhn算法校验
@EAN type:EAN 类型 验证字符串是否是有效的 EAN(欧洲文章编号)码
@ScriptAssert lang:脚本语言
script:脚本内容
alias:脚本别名
reportOn:指定将错误报告应用于哪些属性
验证对象的属性是否满足指定的脚本表达式
@ParameterScriptAssert lang:脚本语言
script:脚本内容
验证对象的属性是否满足指定的脚本表达式,可以在脚本中引用方法参数

校验开启

@Valid和@Validated是用于Spring框架中数据校验的注解。

@Valid和@Validated




































对比 @Valid @Validated
校验规则 JavaEE JSR-303(Bean Validation)规范定义的 Spring定义的,对@Valid进行了二次封装。
所以既支持使用JSR-303规范的注解,也可以使用Spring提供的额外校验规则
使用范围 用在方法、参数、字段上 用在类、参数上
分组校验 不支持 支持
嵌套校验 支持
需要在嵌套的字段上面也加上@Valid
不支持
异常处理 校验失败时抛出异常MethodArgumentNotValidException 校验失败时抛出异常ConstraintViolationException

校验分类

Spring支持校验范围可分为以下两类:

  • Controller校验
  • Spring Bean校验(包括Controller)

- Controller校验

Spring对Controller层的参数校验进行了专门处理,当请求到达Controller层前会先找到匹配的方法参数解析器(HandlerMethodArgumentResolver)进行参数解析,参数解析的过程中包含参数校验。

HandlerMethodArgumentResolver分析可参考:https://blog.csdn.net/JokerLJG/article/details/134754757

源码分析:

HandlerMethodArgumentResolver接口:

  1. public interface HandlerMethodArgumentResolver {
  2. // 判断该解析器是否支持解析给定的方法参数
  3. boolean supportsParameter(MethodParameter parameter);
  4. // 解析给定的方法参数,并返回解析后的参数值
  5. Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
  6. NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
  7. }

下面以HandlerMethodArgumentResolver的其中一个实现类来分析。
RequestResponseBodyMethodProcessor类:

  1. @Override
  2. public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
  3. NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
  4. parameter = parameter.nestedIfOptional();
  5. Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());
  6. String name = Conventions.getVariableNameForParameter(parameter);
  7. if (binderFactory != null) {
  8. WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);
  9. if (arg != null) {
  10. validateIfApplicable(binder, parameter);
  11. if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
  12. throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
  13. }
  14. }
  15. if (mavContainer != null) {
  16. mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
  17. }
  18. }
  19. return adaptArgumentIfNecessary(arg, parameter);
  20. }
  21. protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {
  22. // 遍历方法参数上的注解
  23. Annotation[] annotations = parameter.getParameterAnnotations();
  24. for (Annotation ann : annotations) {
  25. // 如果注解是Validated或注解以Valid开头时,进行参数校验
  26. Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
  27. if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
  28. Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
  29. Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {
  30. hints});
  31. binder.validate(validationHints);
  32. break;
  33. }
  34. }
  35. }
  • 获取方法参数上的所有注解,遍历注解
  • 当注解是Validated或注解以Valid开头时,进行参数校验

- Spring Bean校验

Spring Bean校验底层是通过AOP的方式实现的,通过MethodValidationPostProcessor动态注册AOP切面(以Validated注解为切点),然后使用MethodValidationInterceptor对切点方法织入增强。

注意:Spring Bean校验对Controller及其他Spring Bean都适用。

MethodValidationPostProcessor类:

  1. public void afterPropertiesSet() {
  2. // 为所有`@Validated`标注的Bean创建切面
  3. Pointcut pointcut = new AnnotationMatchingPointcut(this.validatedAnnotationType, true);
  4. // 创建Advisor进行增强
  5. this.advisor = new DefaultPointcutAdvisor(pointcut, createMethodValidationAdvice(this.validator));
  6. }
  7. // 创建Advice,本质就是一个方法拦截器(拦截Bean的所有方法)
  8. protected Advice createMethodValidationAdvice(@Nullable Validator validator) {
  9. return (validator != null ? new MethodValidationInterceptor(validator) : new MethodValidationInterceptor());
  10. }

MethodValidationInterceptor类:

  1. @Override
  2. @SuppressWarnings("unchecked")
  3. public Object invoke(MethodInvocation invocation) throws Throwable {
  4. // 无需增强的方法,直接跳过
  5. if (isFactoryBeanMetadataMethod(invocation.getMethod())) {
  6. return invocation.proceed();
  7. }
  8. // 获取校验分组信息
  9. Class<?>[] groups = determineValidationGroups(invocation);
  10. ExecutableValidator execVal = this.validator.forExecutables();
  11. Method methodToValidate = invocation.getMethod();
  12. Set<ConstraintViolation<Object>> result;
  13. // 方法参数校验
  14. try {
  15. result = execVal.validateParameters(invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
  16. } catch (IllegalArgumentException ex) {
  17. methodToValidate = BridgeMethodResolver.findBridgedMethod(ClassUtils.getMostSpecificMethod(invocation.getMethod(), invocation.getThis().getClass()));
  18. result = execVal.validateParameters(invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
  19. }
  20. if (!result.isEmpty()) {
  21. throw new ConstraintViolationException(result);
  22. }
  23. Object returnValue = invocation.proceed();
  24. // 方法返回值校验
  25. result = execVal.validateReturnValue(invocation.getThis(), methodToValidate, returnValue, groups);
  26. if (!result.isEmpty()) {
  27. throw new ConstraintViolationException(result);
  28. }
  29. return returnValue;
  30. }
  • 方法参数校验:当方法参数上有@Valid或参数校验注解(@NotNull、@NotBlank、@Length等)时,会进行校验。
  • 方法返回值校验:当方法参数上有@Valid或参数校验注解(@NotNull、@NotBlank、@Length等)时,会进行校验。

校验使用


























校验分类 校验范围
Controller 方法参数对象校验 Controller适用
Spring Bean 方法返回值对象校验 Controller及其他Spring Bean都适用
Spring Bean 方法参数对象校验 Controller及其他Spring Bean都适用

注意:下面的示例中,项目做了全局异常处理。

- Controller:参数对象校验

对Controller方法参数对象进行校验。

  1. @Data
  2. public class User {
  3. @NotNull(message = "userId不能为空")
  4. public String userId;
  5. }
  • 使用@Valid+校验注解:

    方法参数上加@Valid,参数对象中使用校验注解

    代码

    1. @RestController
    2. @RequestMapping("valid")
    3. public class ValidController {
  1. @PostMapping("test11")
  2. public User test11(@RequestBody @Valid User user) {
  3. return user;
  4. }
  5. }
  6. 请求
  7. curl 'http://127.0.0.1:8888/valid/test11' -H 'Content-Type: application/json' -d '{
  8. }'
  9. 结果
  10. {
  11. "code": 501,
  12. "msg": "userId不能为空",
  13. "data": null
  14. }
  • 使用@Validated+校验注解:

    方法参数上加@Validated,参数对象中使用校验注解

    代码

    1. @RestController
    2. @RequestMapping("valid")
    3. public class ValidController {
  1. @PostMapping("test12")
  2. public User test12(@RequestBody @Validated User user) {
  3. return user;
  4. }
  5. }
  6. 请求
  7. curl 'http://127.0.0.1:8888/valid/test12' -H 'Content-Type: application/json' -d '{
  8. }'
  9. 结果
  10. {
  11. "code": 501,
  12. "msg": "userId不能为空",
  13. "data": null
  14. }

- Spring Bean:方法返回值对象校验

对Spring Bean(包括Controller)方法返回值对象进行校验。

注意:方法返回值对象校验时,注解放到方法前面或整个方法上面都是相同的效果。

  1. @Data
  2. public class User {
  3. @NotNull(message = "userId不能为空")
  4. public String userId;
  5. }
  • 使用@Validated+@Valid+校验注解

    Spring Bean类上加@Validated,方法返回值上加@Valid,返回值对象中使用校验注解。

    代码

    1. @RestController
    2. @RequestMapping("valid")
    3. public class ValidController {
  1. @Autowired
  2. private ValidService validService;
  3. @PostMapping("test13")
  4. public User test13(@RequestBody User user) {
  5. return validService.test13(user);
  6. }
  7. }
  8. @Validated
  9. @Service
  10. public class ValidService {
  11. public @Valid User test13(User user) {
  12. return user;
  13. }
  14. }
  15. 请求
  16. curl 'http://127.0.0.1:8888/valid/test13' -H 'Content-Type: application/json' -d '{
  17. }'
  18. 结果
  19. {
  20. "code": 501,
  21. "msg": "userId不能为空",
  22. "data": null
  23. }
  • 使用@Validated+校验注解

    Spring Bean类上加@Validated,方法返回值上直接使用校验注解。

    代码

    1. @RestController
    2. @RequestMapping("valid")
    3. public class ValidController {
    4. @Autowired
    5. private ValidService validService;
    6. @PostMapping("test14")
    7. public @NotNull User test14(@RequestBody User user) {
    8. return validService.test14(user);
    9. }
    10. }
    11. @Validated
    12. @Service
    13. public class ValidService {
  1. public @NotNull User test14(User user) {
  2. return null;
  3. }
  4. }
  5. 请求
  6. curl 'http://127.0.0.1:8888/valid/test14' -H 'Content-Type: application/json' -d '{
  7. }'
  8. 结果
  9. {
  10. "code": 501,
  11. "msg": "不能为null",
  12. "data": null
  13. }

- Spring Bean:方法参数对象校验

对Spring Bean(包括Controller)方法参数对象进行校验。

  1. @Data
  2. public class User {
  3. @NotNull(message = "userId不能为空")
  4. public String userId;
  5. }
  • 使用@Validated+@Valid+校验注解

    Spring Bean类上加@Validated,方法参数上加@Valid,参数对象中使用校验注解。

    代码

    1. @RestController
    2. @RequestMapping("valid")
    3. public class ValidController {
  1. @Autowired
  2. private ValidService validService;
  3. @PostMapping("test15")
  4. public User test15(@RequestBody User user) {
  5. return validService.test15(user);
  6. }
  7. }
  8. @Validated
  9. @Service
  10. public class ValidService {
  11. public User test15(@Valid User user) {
  12. return user;
  13. }
  14. }
  15. 请求
  16. curl 'http://127.0.0.1:8888/valid/test15' -H 'Content-Type: application/json' -d '{
  17. }'
  18. 结果
  19. {
  20. "code": 501,
  21. "msg": "userId不能为空",
  22. "data": null
  23. }
  • 使用@Validated+校验注解

    Spring Bean类上加@Validated,方法参数上直接中使用校验注解。

    代码

    1. @RestController
    2. @RequestMapping("valid")
    3. public class ValidController {
  1. @Autowired
  2. private ValidService validService;
  3. @PostMapping("test16")
  4. public User test16(@RequestBody User user) {
  5. return validService.test16(null);
  6. }
  7. }
  8. @Validated
  9. @Service
  10. public class ValidService {
  11. public User test16(@NotNull User user) {
  12. return user;
  13. }
  14. }
  15. 请求
  16. curl 'http://127.0.0.1:8888/valid/test16' -H 'Content-Type: application/json' -d '{
  17. }'
  18. 结果
  19. {
  20. "code": 501,
  21. "msg": "不能为null",
  22. "data": null
  23. }

分组校验

  1. @Data
  2. public class User {
  3. @NotNull(message = "userId不能为空")
  4. public String userId;
  5. @NotNull(message = "userName不能为空", groups = {
  6. AddGroup.class})
  7. public String userName;
  8. @NotNull(message = "age不能为空", groups = {
  9. UpdateGroup.class})
  10. public String age;
  11. }

- Controller:方法参数分组校验

对Controller方法参数对象进行分组校验。

  • 使用@Validated+@Valid+校验注解

    方法参数上加@Validated,并指定分组value属性,参数对象中的字段加校验注解并指定分组groups属性。

    代码

    1. @RestController
    2. @RequestMapping("valid")
    3. public class ValidController {
  1. @PostMapping("test17")
  2. public User test17(@RequestBody @Validated({
  3. AddGroup.class}) User user) {
  4. return user;
  5. }
  6. @PostMapping("test18")
  7. public User test18(@RequestBody @Validated({
  8. UpdateGroup.class}) User user) {
  9. return user;
  10. }
  11. }
  12. 请求
  13. curl 'http://127.0.0.1:8888/valid/test17' -H 'Content-Type: application/json' -d '{
  14. }'
  15. curl 'http://127.0.0.1:8888/valid/test18' -H 'Content-Type: application/json' -d '{
  16. }'
  17. 结果
  18. {
  19. "code": 501,
  20. "msg": "userName不能为空",
  21. "data": null
  22. }
  23. {
  24. "code": 501,
  25. "msg": "age不能为空",
  26. "data": null
  27. }

嵌套校验

  1. @Data
  2. public class User {
  3. @NotNull(message = "userId不能为空")
  4. public String userId;
  5. @Valid
  6. public Sex sex;
  7. }
  8. @Data
  9. public class Sex {
  10. @NotNull(message = "sexName不能为空")
  11. public String sexName;
  12. }

- Controller:方法参数嵌套校验

对Controller方法参数对象进行嵌套校验。

  • 使用@Validated+@Valid+校验注解

    方法参数上加@Validated,参数对象中的字段加@Valid,字段对象内再使用校验注解。

    代码

    1. @RestController
    2. @RequestMapping("valid")
    3. public class ValidController {
  1. @PostMapping("test19")
  2. public User test19(@RequestBody @Validated User user) {
  3. return user;
  4. }
  5. }
  6. 请求
  7. curl 'http://127.0.0.1:8888/valid/test19' -H 'Content-Type: application/json' -d '{
  8. "userId": "userId_a7699554a547",
  9. "sex": {
  10. }
  11. }'
  12. 结果
  13. {
  14. "code": 501,
  15. "msg": "sexName不能为空",
  16. "data": null
  17. }
  • 使用@Valid+@Valid+校验注解

    方法参数上加@Valid,参数对象中的字段加@Valid,字段对象内再使用校验注解。

    代码

    1. @RestController
    2. @RequestMapping("valid")
    3. public class ValidController {
  1. @PostMapping("test20")
  2. public User test20(@RequestBody @Valid User user) {
  3. return user;
  4. }
  5. }
  6. 请求
  7. curl 'http://127.0.0.1:8888/valid/test20' -H 'Content-Type: application/json' -d '{
  8. "userId": "userId_a7699554a547",
  9. "sex": {
  10. }
  11. }'
  12. 结果
  13. {
  14. "code": 501,
  15. "msg": "sexName不能为空",
  16. "data": null
  17. }

- Spring Bean:方法返回值嵌套校验

对Spring Bean(包括Controller)方法返回值对象进行嵌套校验。

  • 使用@Validated+@Valid+@Valid+校验注解

    Spring Bean类上加@Validated,方法返回值上加@Valid,返回值对象中字段加@Valid,字段内使用校验注解。

    代码

    1. @RestController
    2. @RequestMapping("valid")
    3. public class ValidController {
  1. @Autowired
  2. private ValidService validService;
  3. @PostMapping("test21")
  4. public User test21(@RequestBody User user) {
  5. return validService.test21(user);
  6. }
  7. }
  8. @Validated
  9. @Service
  10. public class ValidService {
  11. public @Valid User test21(User user) {
  12. return user;
  13. }
  14. }
  15. 请求
  16. curl 'http://127.0.0.1:8888/valid/test21' -H 'Content-Type: application/json' -d '{
  17. "userId": "userId_a7699554a547",
  18. "sex": {
  19. }
  20. }'
  21. 结果
  22. {
  23. "code": 501,
  24. "msg": "sexName不能为空",
  25. "data": null
  26. }

- Spring Bean:方法参数嵌套校验

对Spring Bean(包括Controller)方法参数对象进行嵌套校验。

  • 使用@Validated+@Valid+@Valid+校验注解

    Spring Bean类上加@Validated,方法参数上加@Valid,参数对象中字段加@Valid,字段内使用校验注解。

    代码

    1. @RestController
    2. @RequestMapping("valid")
    3. public class ValidController {
  1. @Autowired
  2. private ValidService validService;
  3. @PostMapping("test22")
  4. public User test22(@RequestBody User user) {
  5. return validService.test22(user);
  6. }
  7. }
  8. @Validated
  9. @Service
  10. public class ValidService {
  11. public User test22(@Valid User user) {
  12. return user;
  13. }
  14. }
  15. curl 'http://127.0.0.1:8888/valid/test22' -H 'Content-Type: application/json' -d '{
  16. "userId": "userId_a7699554a547",
  17. "sex": {
  18. }
  19. }'
  20. 结果
  21. {
  22. "code": 501,
  23. "msg": "sexName不能为空",
  24. "data": null
  25. }

自定义注解

自定义参数校验工具的步骤:

  1. 自定义注解
  2. 自定义Validator

1. 自定义注解

定义一个IPV4地址的校验注解。

  1. import javax.validation.Constraint;
  2. import javax.validation.Payload;
  3. import java.lang.annotation.*;
  4. import static java.lang.annotation.ElementType.*;
  5. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  6. @Documented
  7. @Target({
  8. METHOD, FIELD, PARAMETER, TYPE_USE })
  9. @Retention(RUNTIME)
  10. @Repeatable(Ipv4.List.class)
  11. @Constraint(validatedBy = {
  12. Ipv4Validator.class})
  13. public @interface Ipv4 {
  14. String message() default "not is Ipv4";
  15. Class<?>[] groups() default {
  16. };
  17. Class<? extends Payload>[] payload() default {
  18. };
  19. @Target({
  20. METHOD, FIELD, PARAMETER, TYPE_USE })
  21. @Retention(RUNTIME)
  22. @Documented
  23. @interface List {
  24. Ipv4[] value();
  25. }
  26. }

2. 自定义Validator

定义一个校验器,用于验证是否为IPV4地址。

  1. import cn.hutool.core.lang.Validator;
  2. import javax.validation.ConstraintValidator;
  3. import javax.validation.ConstraintValidatorContext;
  4. public class Ipv4Validator implements ConstraintValidator<Ipv4, String> {
  5. @Override
  6. public void initialize(Ipv4 constraintAnnotation) {
  7. ConstraintValidator.super.initialize(constraintAnnotation);
  8. }
  9. @Override
  10. public boolean isValid(String value, ConstraintValidatorContext context) {
  11. // 对象为空验证通过
  12. if (value == null) {
  13. return true;
  14. }
  15. return Validator.isIpv4(value);
  16. }
  17. }

使用示例:

代码

  1. @Validated
  2. @RestController
  3. @RequestMapping("valid")
  4. public class ValidController {
  5. @GetMapping("test23")
  6. public String test23(@Ipv4(message = "ip不是IPV4地址") String ip) {
  7. return ip;
  8. }
  9. }

请求

  1. curl 'http://127.0.0.1:8888/valid/test23?ip=1.1.1'

结果

  1. {
  2. "code": 501,
  3. "msg": "ip不是IPV4地址",
  4. "data": null
  5. }

发表评论

表情:
评论列表 (有 0 条评论,135人围观)

还没有评论,来说两句吧...

相关阅读

    相关 SpringBoot 注解校验参数

    在项目开发中我们经常会遇到各种参数校验,尤其是表单参数的校验。当参数不多时我们可以在控制器中手动校验,但是一旦遇到需要校验的参数较多的post接口时,还去一个个的校验的话那会累