1.为什么使用hibernate validate

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

if (userName == null || "".equals(userName)) {
response.setCode(10001);
response.setMessage("用户名不能为空!");
return response;
}

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

2.hibernate validate简介

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

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包,需要手动添加,依赖信息如下:

<!-- 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配置,配置内容如下:

@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之后,在全项目中使用,并且能多次使用.

创建对象:

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方法)
}

运行以下测试类:

@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位之前

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

@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 自定义校验规则

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

首先定义注解:

@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 { };
}

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

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的定义修改如下:

@NotBlank(message = "公司名称不能为空")
@CharLength(max = 12, message = "公司名称不能超过12个字符")
private String name;

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

2.3 使用@ScriptAssert校验参数

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

在Company类上添加以下注解:

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

并定义校验方法:

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/

使用hibernate validate做参数校验的更多相关文章

  1. 如何在 Spring/Spring Boot 中做参数校验?你需要了解的都在这里!

    本文为作者原创,如需转载请在文首著名地址,公众号转载请申请开白. springboot-guide : 适合新手入门以及有经验的开发人员查阅的 Spring Boot 教程(业余时间维护中,欢迎一起维 ...

  2. 如何在 Spring/Spring Boot 中做参数校验

    数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据. 本文结合自己在项目 ...

  3. spring mvc +@Valid +@RequestBody 来做参数校验返回400,并且不显示具体message 如何解决

    参考文档: https://www.oschina.net/question/115867_2282711   谢谢原作者

  4. eggjs的参数校验模块egg-validate的使用和进一步定制化升级

    简单讲一下这个egg-validate egg-validate是基于parameter的. 安装 npm install --save egg-validate 启用 // config/plugi ...

  5. 全栈项目|小书架|服务器开发-Koa2 参数校验处理

    为什么需要做参数校验 在开发中,无论是App开发还是服务器接口开发, 我们无法去预测用户传入的数据,因此参数(数据)校验是开发中不可或缺的一环. 例如像App的注册登录表单提交页面,就要做好多层的判断 ...

  6. SpringBoot中通过实现WebMvcConfigurer完成参数校验

    在Spring5.0和SpringBoot2.0中废弃了WebMvcConfigurerAdapter类. 现有两种解决方案 1 直接实现WebMvcConfigurer (官方推荐)2 直接继承We ...

  7. 为List&lt;T&gt;中的T进行参数校验

    1.现在前端发送了一个POST请求,他的Data是一个数组,而不是对象(jsonObj的值两侧是中括号). var jsonObj = [{'id':11, 'name':'叵'}, {'id':12 ...

  8. hibernate.validator.constraints.NotEmpty校验请求参数报错java.lang.NoClassDefFoundError: javax/el/PropertyNotFoundException

    spring maven项目,使用hibernate validator 注解形式校验客户端的请求参数. hibernate-validator版本:5.0.2.Final validation-ap ...

  9. 使用Hibernate Validator来帮你做数据校验

    数据校验是贯穿所有应用程序层(从表示层到持久层)的常见任务.通常在每个层中实现相同的验证逻辑,这是耗时且容易出错的.这里我们可以使用Hibernate Validator来帮助我处理这项任务.对此,H ...

  10. Hibernate Validator参数校验

    日常开发中经常会遇到需要参数校验的情况,比如某个字段不能为空.长度不能超过5等都属于参数校验的范围.对于简单的参数校验通过写几个if-else判断语句就搞定,但是对于复杂的多个参数校验的情况,就不是那 ...

随机推荐

  1. Netty In Action

    1 introduction 1.2 Asynchronous by design two most common ways to work with or implement an asynchro ...

  2. [转]Excel 取汉字拼音首位

    转自:http://jingyan.baidu.com/article/63acb44adca44461fcc17e85.html 转自:http://jingyan.baidu.com/articl ...

  3. Discuz! X的CSS加载机制

    首先,每个页面都会加载以下两个css,data/cache/style_1_common.css和data/cache/style_1_forum_index.css.先讲讲这两个文件名的命名规则:第 ...

  4. es6新特性

    变量-------------------------- let, const:必须直接给一个变量赋值.注意,对象的属性或数组成员还是可以改变的. const MY_OBJECT = {some: 1 ...

  5. logcat保存当前应用程序的日志并上传服务器或指定邮箱

    给大家分享一个项目中用到的日志统计并提交服务器的日志工具类.通过过得当前app的PID,采用命令行的方式实用logcat工具过滤日志.代码区: package org.and.util; import ...

  6. PMBOK 项目管理 九大知识领域和五大流程

    PMI   Project Management Institute.PMI 是世界上最大的非盈利机构,是项目管理领域的领导者.PMI制定项目管理行业标准,带领项目管理的研究并提供项目管理的培训,证书 ...

  7. java中如何调用oracle存储过程

    在java中使用CallableStatement调用存储过程 列: 创建需要的测试表:create table Test(tid varchar2(10),tname varchar2(10)): ...

  8. 用Laravel Sms实现 laravel短信验证码的发送

    使用Laravel Sms这个扩展包实现短信验证码的发送,这里以阿里云的短信服务为例: 首先,要创建短信签名和短信模板,具体申请详情如下, 接下来,需要创建AccessKey,由于AccessKey是 ...

  9. 5-Redis 的持久化之 RDB

    2016-12-22 13:58:48 该系列文章链接NoSQL 数据库简介Redis的安装及及一些杂项基础知识Redis 的常用五大数据类型(key,string,hash,list,set,zse ...

  10. c# 关于async/await异步编程的浅析和使用

    线程的同步运行,时效性慢,异步运行,时效性快! 在c#5.0引出了async/await关键字,可以用其来进行异步编程. async/await定义异步方法的语法如下: 1.在方法的返回类型前面加上a ...