API接口参数验证的必备神器,让你的代码更高效!

欧易OKX

欧易OKX

               

欧易OKx是全球三大比特币交易所之一,注册即开最高6万元盲盒,100%中奖!

           官网注册
类上必须有@Validated注解;因为上面的BeanPostProcessor中定义的Advisor(DefaultPointcutAdvisor)使用的切入的Pointcut在类级别上过滤条件是必须有@Validated注解,而方法则是拦截所有的方法。

环境:Springboot2.6.12

1. 简介

Spring Validation是一种轻量级的数据验证框架,主要用于对Java对象进行校验。它为数据验证提供了统一的接口和基本的校验功能,解决了数据校验这一常见问题,让开发人员能够方便地对数据进行验证,从而保证数据的有效性和安全性。

Spring Validation提供了一套注解,用于对Java对象进行校验,支持嵌套校验和分组校验,支持国际化和自定义注解和校验器,可以满足各种复杂的校验需求。它的主要特点包括:

  1. 轻量级:Spring Validation只做验证相关的事情,不包含复杂的业务逻辑。
  2. 简单易用:基于注解,简洁明了,易于维护。
  3. 校验规则灵活:支持自定义校验规则,可扩展性强。
  4. 支持国际化:根据不同的语言环境,使用不同的校验提示消息。
  5. 集成Hibernate Validator:Spring Validation默认使用Hibernate Validator作为其具体的实现,可以轻松地与其他数据验证框架一起工作。

 

Bean Validation 为Java应用程序提供了一种通过约束声明和元数据进行验证的通用方法。要使用它,只需要对POJO属性进行注释,然后由运行时强制执行这些约束。有内置的约束,你也可以定义自己的自定义约束。如下所示:

public class Person {


  @NotNull
  @Size(max=64)
  private String name;
  @Min(0)
  private int age;


}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

Bean验证验证器然后根据声明的约束验证此类的实例。有关API的一般信息,请参见Bean验证。有关特定约束,请参阅Hibernate验证程序文档。

配置Bean验证提供程序

Spring提供了对Bean验证API的全面支持,包括将Bean验证提供者作为Spring Bean。这使你可以在应用程序中需要验证的任何位置注入javax.validation.ValidatorFactory或javax.validation.Validator。

你可以使用LocalValidatorFactoryBean将默认验证器配置为Spring Bean,如下例所示:

import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;


@Configuration
public class AppConfig {


  @Bean
  public LocalValidatorFactoryBean validator() {
    return new LocalValidatorFactoryBean();
  }


}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

上面的示例中的基本配置使用默认引导机制触发bean验证进行初始化。Bean验证提供程序(如Hibernate验证程序)应该出现在类路径中,并被自动检测到。

 

2. 注入 Validator

 

@Service
public class PersonService {
  // inject javaee validator object
  @Resource
  private Validator validator ;
  // inject spring validator object
  @Resource
  private org.springframework.validation.Validator valid ;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

简单实例

接着上面的配置,我们只需要做验证动作即可。

@Service
public class PersonService {


  @Resource
  private Validator validator ;
  @Resource
  private org.springframework.validation.Validator valid ;




  public void validator(Person person) {
    Set<ConstraintViolation<Person>> res = validator.validate(person) ;
    res.forEach(cv -> {
      System.out.println(cv.getMessage()) ;
    });
    System.out.println("----------------------") ;
    BindingResult errors = new MapBindingResult(new HashMap<String, Object>(), "person") ;
    valid.validate(person, errors) ;
    if (errors.hasErrors()) {
      errors.getAllErrors().forEach(oe -> {
        System.out.println(oe.getDefaultMessage()) ;
      });
    }
  }


}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.

测试

@SpringBootTest
class SpringBootValidationApplicationTests {


  @Resource
  private PersonService ps ;


  @Test
  public void testValidator() {
    Person person = new Person() ;
    person.setAge(-1);
    ps.validator(person) ;
  }


}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

最小不能小于0
不能为null
----------------------
最小不能小于0
不能为null
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

3. 自定义注解验证

每个Bean验证约束由两部分组成:

  • 声明约束及其可配置属性的@Constraint注释。
  • 实现约束行为的javax.validation.ConstraintValidator接口的实现。

要将声明与实现关联,每个@Constraint注释都会引用相应的ConstraintValidator实现类。在运行时,当域模型中遇到约束注释时,ConstraintValidatorFactory将实例化引用的实现。下面的示例实现一个前缀匹配的验证逻辑:

 

自定义注解

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PrefixConstraintValidator.class)
public @interface PrefixConstraint {


  String value() default "" ;
  // 这里的{validator.prefix.error}就是资源文件中定义的错误信息
  String message() default "{validator.prefix.error}";


  Class<?>[] groups() default { };


  Class<? extends Payload>[] payload() default { };


}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

以上的注解属性都是必须的。

注意message属性是我们将发生错误后错误信息定义在配置文件中,而该文件的basename必须是ValidationMessages,如果你需要国际化支持,那么就这样命名:ValidationMessages_zh_CN.properties。

 

自定义验证器

public class PrefixConstraintValidator implements ConstraintValidator<PrefixConstraint, CharSequence> {


  @Resource
  private DataService ds ;


  private String prefix ;


  @Override
  public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
    ds.ak() ;
    if ( value == null ) {
      return false ;
    }
    return ((String) value).startsWith(prefix) ;
  }


  @Override
  public void initialize(PrefixConstraint pc) {
    prefix = pc.value() ;
  }


}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.

验证器必须实现ConstraintValidator接口,该接口是泛型接口,第一个参数是该验证器要用于在那个注解,第二个参数是该注解应用在什么数据类型上。注意:在自定义验证器中我们是可以随意地注入其它Bean对象,是不是很强大?

基于方法级的验证

你可以通过MethodValidationPostProcessor Bean定义将Bean validation 1.1(以及Hibernate Validator 4.3的自定义扩展)支持的方法验证功能集成到Spring上下文中:

@Bean
public MethodValidationPostProcessor validationPostProcessor() {
  return new MethodValidationPostProcessor();
}
@Service
@Validated
public class PersonService {


  @NotNull(message = "返回值不能为空")
  public Person findPerson(@NotEmpty(message = "ID 不能为空") String id) {
    return null ;
  }


}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

注意:类上必须有@Validated注解;因为上面的BeanPostProcessor中定义的Advisor(DefaultPointcutAdvisor)使用的切入的Pointcut在类级别上过滤条件是必须有@Validated注解,而方法则是拦截所有的方法。

 

测试

图片

这里是抛出的异常javax.validation.ConstraintViolationException,所有我们需要一个全局的异常拦截器来对异常做处理。

其他配置选项

默认的LocalValidatoryFactoryBean配置对于大多数情况都足够了。对于各种Bean验证构造,有许多配置选项,从消息插值到遍历解析。有关这些选项的更多信息,请参阅LocalValidatorFactoryBean Javadoc。

风险提示:根据央行等部门发布“关于进一步防范和处置虚拟货币交易炒作风险的通知”,本网站内容仅用于信息分享,不对任何经营与投资行为进行推广与背书,请读者严格遵守所在地区法律法规,不参与任何非法金融行为。本文收集整理自网络,不代表经典网立场,如若转载,请注明出处:https://www.jingdian230.com/baike/135076.html

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台用户上传并发布,本平台仅提供信息存储服务。

Special statement: The above contents (including pictures or videos, if any) are uploaded and released by users of the we-media platform. This platform only provides information storage services.

(0)
欧易OKX

欧易OKX

               

欧易OKx是全球三大比特币交易所之一,注册即开最高6万元盲盒,100%中奖!

           官网注册

相关推荐

  • 学吊车的最佳方法

    ①学吊车的最佳方法 1、每台小吊车的司机,都必须经过培训、考核合格,并持有操作证才准予操作。 2、司机接班时,应检查制动器、吊钩、钢丝绳和安全装置。发现性能不正常,应在操作前排除。…

    金色百科 2024年 3月 29日
    43
  • 翩翩君子温润如玉是什么意思(翩翩君子温润如玉名字)

    很多人对翩翩君子温润如玉是什么意思(翩翩君子温润如玉名字)这个问题比较感兴趣,这里,金色百科小编大浪就给大家详细解答一下。 翩翩君子温润如玉是指谦虚而严格要求自己的人,温润如玉是一…

    金色百科 2023年 5月 22日
    169
  • 选择制冷剂有什么要求

    一)选择制冷剂有什么要求 1、对人类生态环境无破坏作用; 2、临 界温度较高。在常温或普通低温下能够液化,临界温度比环境温度高的多,才能减少制冷剂节流损失,提高循环经济性; 3、在…

    2024年 3月 9日
    56
  • 集运仓什么意思(集运仓上架什么意思)

    很多人对集运仓什么意思(集运仓上架什么意思)这个问题比较感兴趣,这里,金色百科小编大飞就给大家详细解答一下。 集运仓是你人在国外,但想在国内网购商品,比如在国内购物平台购买商品后,…

    金色百科 2023年 5月 2日
    139
  • 今期猴狗鼠出特,古来万事贵天生代表什么生肖,答案已答梳理落实

    今期猴狗鼠出特,古来万事贵天生指的是生肖羊、是生肖牛、是生肖马。 今期猴狗鼠出特,古来万事贵天生在十二生肖中代表的是生肖羊、是生肖牛、是生肖马。 生肖羊 生肖羊友温柔体贴。他们真诚…

    金色百科 2024年 1月 15日
    155
  • 望其项背是什么意思

    导读:望其项背是什么意思,望其项背而不及的意思,望其项背的意思赶不上,望其项背比喻什么,令人望其项背是病句吗,望其项背的意思和例句,望其项背是褒义还是贬义,终其一生难以望其项背,望…

    金色百科 2023年 3月 20日
    455
  • 2024年1月28日宜旅游出外吗 是出行上等吉日吗

    2024年1月28日出行好不好 公元:2024年1月28日,星期日农历:二零二三年腊月十八岁次:癸卯年、乙丑月、辛卯日生肖:属相兔,水瓶座胎神占方:占厨灶门外正北今日冲:冲鸡煞西黄…

    2024年 1月 12日
    109
  • csdn是什么意思(csdn是什么意思)

    很多人对csdn是什么意思(csdn是什么意思)这个问题比较感兴趣,这里,金色百科小编小张就给大家详细解答一下。 1、是中国软件开发者网络。 2、在“中国的软件开发者网络”或“中国…

    金色百科 2023年 5月 17日
    189
  • 欧易OKX

    欧易OKX

                   

    欧易OKx是全球三大比特币交易所之一,注册即开最高6万元盲盒,100%中奖!

               官网注册
  • 笃行是什么意思

    笃行是什么意思很多人对这个问题比较感兴趣,这里,金色百科小编小币就给大家详细解答一下。 (1)笃行的意思是什么 相信大家都见过“笃行”这个词,可以说是非常特别的一个词,那么大家知道…

    2023年 2月 21日
    229
  • 越来越甜的水果会不健康吗 越来越甜的水果会不健康吗英文

    现在的水果比以前的口味更好了,尤其是甜度上,是越来越甜了,但也有一些人就会担心影响健康,那么,越来越甜的水果会不健康吗?水果为什么越来越甜了?下面小编就带来介绍。 越来越甜的水果会…

    金色百科 2024年 1月 13日
    111