前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用hibernate validate做参数校验

使用hibernate validate做参数校验

作者头像
代码改变世界-coding
发布2020-08-02 17:28:24
9220
发布2020-08-02 17:28:24
举报
文章被收录于专栏:java相关
1.为什么使用hibernate validate

​ 在开发http接口的时候,参数校验是必须有的一个环节,当参数校验较少的时候,一般是直接按照校验条件做校验,校验不通过,返回错误信息。比如以下校验用户名不为空的校验:

代码语言:javascript
复制
if (userName == null || "".equals(userName)) {
    response.setCode(10001);
    response.setMessage("用户名不能为空!");
    return response;
}

但是当接口参数很多,并且参数校验很负责的时候,如果继续使用这种校验的方式,校验代码会非常多,并且难以维护。那么在这种情况下可以考虑使用hibernate validate做参数校验。

2.hibernate validate简介

hibernate validate是基于注解来实现的参数校验框架,并且有很好的扩展性,使用者可以通过自定义约束条件来实现自定义的校验条件。以下为添加注解的一个小例子:

代码语言:javascript
复制
public class Car {

   @NotNull
   private String manufacturer;

   @NotNull
   @Size(min = 2, max = 14)
   private String licensePlate;

   @Min(2)
   private int seatCount;
}
2.1 springboot项目做基本校验

​ 新建springboot项目,并且在项目中添加hibernate validate依赖,在springboot2.0版本中的spring-boot-starter-web已经包含了此jar包,不需要再重复添加,但是在spring-boot-starter-web2.0以上版本中不包含此jar包,需要手动添加,依赖信息如下:

代码语言:javascript
复制
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.5.Final</version>
</dependency>

添加Validator的bean配置,配置内容如下:

代码语言:javascript
复制
@Configuration
public class ValidatorConfiguration {

    @Bean
    public Validator validator(){

        ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
                .configure()
                .addProperty( "hibernate.validator.fail_fast", "true" )
                .buildValidatorFactory();
        Validator validator = validatorFactory.getValidator();

        return validator;
    }
}

Validator的实现必须是线程安全的,因此可以配置了bean之后,在全项目中使用,并且能多次使用.

创建对象:

代码语言:javascript
复制
public class Company {

    @NotBlank(message = "商品名称不能为空")
    private String name;

    @Size(min = 2, max = 10, message = "税号长度必须在2到10位之前")
    private String taxNum;

    @Min(13)
    @Pattern(regexp = "[+-]?[0-9.]+$", message = "手机号码只能是数字")
    private String phoneNum;

    public String getName() {
        return name;
    }
    ....(相关get和set方法)
}

运行以下测试类:

代码语言:javascript
复制
@SpringBootTest
class HibernateValidateDemoApplicationTests {
    @Autowired
    protected Validator validator;
    @Test
    void contextLoads() {
        Company company = buildCompany();

        Set<ConstraintViolation<Company>> validResultSet = validator.validate(company);
        for (ConstraintViolation<Company> validResult : validResultSet) {
            System.out.println(validResult.getMessage());
        }
    }
    private Company buildCompany() {
        Company company = new Company();
        company.setName("中国石化(浙江石油分公司)");
        company.setTaxNum("123123123123");
        company.setPhoneNum("13333333333");
        return company;
    }
}

输出结果为:税号长度必须在2到10位之前

以上例子中的注解比较简单,通过添加

代码语言:javascript
复制
@NotBlank(message = "商品名称不能为空")
@Size(min = 2, max = 10, message = "税号长度必须在2到10位之前")
@Min(13)
@Pattern(regexp = "[+-]?[0-9.]+$", message = "手机号码只能是数字") 通过正则表达式校验字符窜

来做一些字符串非空、长度的校验.常用的校验注解有以下几种:

注解

校验规则

AssertFalse、AssertTrue

判断值是否为false或者true

DecimalMax、DecimalMin

必须为数字,并且值小于最大值、大于最小值

Digits

必须是数字

Email

必须是邮箱

Max、Min、NotBlank、NotEmpty、Size

最大最小长度校验

Negative、NegativeOrZero

数值校验

Pattern

正则表达式校验

2.2 自定义校验规则

除了上面框架提供的校验规则, 我们也可以自定义校验规则,比如当我们要校验字符个数的时候,可以使用一下自定义规则。

首先定义注解:

代码语言:javascript
复制
@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = CharacterValidator.class)
@Documented
public @interface CharLength {

    int min() default 0;

    int max() default Integer.MAX_VALUE;

    String message() default "{org.hibernate.validator.constraints.Length.message}";

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

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

定义此注解对应的校验实现类:

代码语言:javascript
复制
public class CharacterValidator implements ConstraintValidator<CharLength, String> {

    private static final Log log = LoggerFactory.make(MethodHandles.lookup());

    private int min;

    private int max;

    @Override
    public void initialize(CharLength constraintAnnotation) {
        min = constraintAnnotation.min();
        max = constraintAnnotation.max();
        validateParameters();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
    //为具体的校验规则
        if ( value == null ) {
            return true;
        }

        int length = CharUtil.getStringLength(value);
        return length >= min && length <= max;
    }

    private void validateParameters() {
        if ( min < 0 ) {
            throw log.getMinCannotBeNegativeException();
        }
        if ( max < 0 ) {
            throw log.getMaxCannotBeNegativeException();
        }
        if ( max < min ) {
            throw log.getLengthCannotBeNegativeException();
        }
    }
}

定义完成之后,对Company的定义修改如下:

代码语言:javascript
复制
@NotBlank(message = "公司名称不能为空")
@CharLength(max = 12, message = "公司名称不能超过12个字符")
private String name;

再次运行测试用例,输出内容如下:公司名称不能超过12个字符

2.3 使用@ScriptAssert校验参数

但是当我们的校验规则更加复杂的时候,只是用注解可能不能完成我们的需求,这个时候就可以使用@ScriptAssert注解来实现运行方法的方式来实现复杂校验。

在Company类上添加以下注解:

代码语言:javascript
复制
@ScriptAssert(lang = "javascript", script = "com.zjut.hibernate.validate.business.CompanyValidateScript.checkCombineLength(_this.name,_this.taxNum, 30)",
        message = "名称和税号不能超过30位")

并定义校验方法:

代码语言:javascript
复制
public static boolean checkCombineLength(int maxLength, String... params) {
    int length = 0;
    for (String param : params) {
        if (StringUtils.isEmpty(param)) {
            continue;
        }
        length += CharUtil.getStringLength(param);
    }
    return length <= maxLength;
}

除此之外,hibernater validate还支持分组校验、校验集合等功能,具体可参考官方文档:

http://hibernate.org/validator/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-08-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.为什么使用hibernate validate
  • 2.hibernate validate简介
    • 2.1 springboot项目做基本校验
      • 2.2 自定义校验规则
        • 2.3 使用@ScriptAssert校验参数
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档