Hibernate Validation验证
Hibernate Validation是一个后端验证框架,目前比较流行的验证做法:前端jquery-form-validate + 后端hibernate-validate,提到Hibernate Validator就不得不提JSR 303-Bean Validation规范,JSR-303 是Java EE 6 中的一项子规范,叫做Bean Validation,官方参考实现是Hibernate Validator,此实现与Hibernate ORM 没有任何关系,JSR 303 用于对Java Bean 中的字段的值进行验证,提供了JSR 303规范中所有内置constraint的实现,除此之外还有一些附加的constraint。
二、hibernate Validation constraint 注解
2.1、Bean Validation 中内置的 constraint(约束)
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
2.2、Hibernate Validator 附加的constraint
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内
hibernate补充的注解中,最后3个不常用,可忽略。
主要区分下@NotNull @NotEmpty @NotBlank 3个注解的区别:
@NotNull 任何对象的value不能为null
@NotEmpty 集合对象的元素不为0,即集合不为空,也可以用于字符串不为null
@NotBlank 只能用于字符串不为null,并且字符串trim()以后length要大于0
三、使用
Hibernate Validation的使用非常简单,只用在相应的实体类中加上注解,再调用对应的校验API方法即可。
A)配置validator
首先要在Spring的配置文件中进行配置,有以下几种方式:
1.在spring3之后,任何支持JSR303的validator(如Hibernate Validator)都可以通过简单配置引入,只需要在配置xml中加入,这时validatemessage的属性文件默认为classpath下的ValidationMessages.properties:
<!-- support JSR303 annotation if JSR 303 validation present on classpath -->
<mvc:annotation-driven />
2.如果不使用默认,可以使用下面配置:
<mvc:annotation-driven validator="validator" />
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<!--不设置则默认为classpath下的ValidationMessages.properties -->
<property name="validationMessageSource" ref="validatemessageSource"/>
</bean>
<bean id="validatemessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:validatemessages"/>
<property name="fileEncodings" value="utf-8"/>
<property name="cacheSeconds" value="120"/>
</bean>
B)配置validator验证规则
package com.fendo.pays.request;
import java.util.Date;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;
/**
* @Title: UserRequest.java
* @Package com.fendo.pays.request
* @Description: 用户请求参数
* @author fendo
* @date 2017年10月2日 下午11:36:17
* @version V1.0
*/
public class UserRequest {
private String id; //唯一标识
@Size(min=1,max=30,message="{user.name.length.error}")
private String name; //姓名
@NotBlank(message="{user.password.isNull}")
@Pattern(regexp="^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,10}$", message="{user.password.error}")
private String password; //密码
private String idcard; //银行卡号
@NotBlank(message="{user.email.isNull}")
@Email(message="{user.email.error}")
private String email; //邮箱
@NotEmpty(message="{user.addres.isNull}")
private String addres; //地址
@Pattern(regexp="^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$", message="{user.mobile.error}")
private String mobile; //手机号
@NotNull(message="{user.highbloodpressure.isNull}")
@Min(value=1,message="{user.highbloodpressure.error}")
private Double highbloodpressure; //血压高
@NotNull(message="{user.Lowbloodpressure.isNull}")
@Min(value=1,message="{user.Lowbloodpressure.error}")
private Double Lowbloodpressure; //血压低
private Integer idcardnum; //银行卡数
@DateTimeFormat(pattern="yyyy-MM-dd")
@NotNull(message="{user.createtime.isNull}")
private Date createtime;//创建日期
.........
}
在Resource目录下新建ValidationMessages.properties配置文件,内容为:
#配置错误提示信息
user.name.length.error=请输入1到30个字符的商品名称
user.createtime.isNull=请输入商品的生产日期
user.email.error=请输入正确的邮箱
user.email.isNull=邮箱不能为空
user.mobile.error=请输入正确的手机号
user.password.isNull=请输入密码
user.password.error=密码必须是6~10位数字和字母的组合
user.highbloodpressure.isNull=血压高不能为空
user.highbloodpressure.error=血压高的值最低为1
user.Lowbloodpressure.isNull=血压低不能为空
user.Lowbloodpressure.error=血压高的值最低为1
user.addres.isNull=地址不能为空
在实体类中直接使用{user.createtime.isNull}方法就能获取得到。。
C)使用validator
在Spring中使用validator有以下几种方式:
1.在需要校验的对象前增加@Valid 注解(该注解位于javax.validation包中)来触发校验。这样就可以完成针对输入数据User对象的校验了,校验结果任然保存在BindingResult对象中。
@RequestMapping(value = "/addusers", method = RequestMethod.GET)
@ResponseBody
public SimpleResult AddUsers(@Valid UserRequest userrequest,BindingResult bindingResult) throws Exception {
SimpleResult simpleResult=SimpleResult.success();
LOGGER.info("[/user/addusers]");
//获取校验错误信息
if(bindingResult.hasErrors()) {
// 输出错误信息
List<FieldError> allErrors = bindingResult.getFieldErrors();
for (FieldError objectError : allErrors) {
System.out.println(objectError.getDefaultMessage());
// 将错误信息传到页面
//simpleResult.put(objectError.getField(), objectError.getDefaultMessage());
return simpleResult.error(SimpleCode.ERROR.getCode(), objectError.getDefaultMessage());
}
}
System.out.println(userrequest.toString());
//使用日起转换器工具类
ConvertUtils.register(new DateLocaleConverter(), Date.class); //不灵活,自己实现最好
UserEntity userEntity=new UserEntity();
BeanUtils.copyProperties(userrequest, userEntity);
userEntity.setId(UUIDTool.getUUID());
userService.insertUser(userEntity);
return simpleResult;
}
或者是使用@Validated注解,都差不多:
@RequestMapping(value = "/adduser", method = RequestMethod.GET)
@ResponseBody
@SystemControllerLog(modelName="UserController",option="AddUser",description = "新增用户")
public SimpleResult AddUser(Model model,@Validated UserRequest userrequest,BindingResult bindingResult) throws Exception {
SimpleResult simpleResult=SimpleResult.success();
LOGGER.info("[/user/adduser]");
//获取校验错误信息
if(bindingResult.hasErrors()) {
// 输出错误信息
List<FieldError> allErrors = bindingResult.getFieldErrors();
for (FieldError objectError : allErrors) {
System.out.println(objectError.getDefaultMessage());
// 将错误信息传到页面
//simpleResult.put(objectError.getField(), objectError.getDefaultMessage());
return simpleResult.error(SimpleCode.ERROR.getCode(), objectError.getDefaultMessage());
}
}
System.out.println(userrequest.toString());
//使用日起转换器工具类
ConvertUtils.register(new DateLocaleConverter(), Date.class); //不灵活,自己实现最好
UserEntity userEntity=new UserEntity();
BeanUtils.copyProperties(userrequest, userEntity);
userEntity.setId(UUIDTool.getUUID());
userService.insertUser(userEntity);
return simpleResult;
}
2.通过Spring注入validator来验证:
@Autowired
private Validator validator;
@RequestMapping(value = "/adduseres", method = RequestMethod.GET)
@ResponseBody
@SystemControllerLog(modelName="UserController",option="AddUser",description = "新增用户")
public SimpleResult AddUseres(UserRequest userrequest) throws Exception {
SimpleResult simpleResult=SimpleResult.success();
LOGGER.info("[/user/adduseres]");
if(validates(validator, userrequest)!=null){
return simpleResult.error(SimpleCode.ERROR.getCode(), validates(validator, userrequest));
}
System.out.println(userrequest.toString());
//使用日起转换器工具类
//ConvertUtils.register(new DateLocaleConverter(), Date.class); //不灵活,自己实现最好
UserEntity userEntity=new UserEntity();
//BeanUtils.copyProperties(userrequest, userEntity);
BeanUtilsExs.copyProperties(userrequest, userEntity);
userEntity.setId(UUIDTool.getUUID());
userService.insertUser(userEntity);
return simpleResult;
————————————————
JAVA中通过Hibernate-Validation进行参数验证
在开发JAVA服务器端代码时,我们会遇到对外部传来的参数合法性进行验证,而hibernate-validator提供了一些常用的参数校验注解,我们可以拿来使用。
1.maven中引入hibernate-validator对应的jar:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.3.1.Final</version>
</dependency>
2.在Model中定义要校验的字段:
|
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
30
31
32
33
34
35
|
import javax.validation.constraints.Pattern;import javax.validation.constraints.Size;import org.hibernate.validator.constraints.NotEmpty;public class PayRequestDto { /** * 支付完成时间 **/ @NotEmpty(message="支付完成时间不能空") @Size(max=14,message="支付完成时间长度不能超过{max}位") private String payTime; /** * 状态 **/ @Pattern(regexp = "0[0123]", message = "状态只能为00或01或02或03") private String status; public String getPayTime() { return payTime; } public void setPayTime(String payTime) { this.payTime = payTime; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; }} |
3.定义Validation工具类:
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.hibernate.validator.HibernateValidator;
import com.atai.framework.lang.AppException;
public class ValidationUtils {
/**
* 使用hibernate的注解来进行验证
*
*/
private static Validator validator = Validation
.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();
/**
* 功能描述: <br>
* 〈注解验证参数〉
*
* @param obj
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static <T> void validate(T obj) {
Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj);
// 抛出检验异常
if (constraintViolations.size() > 0) {
throw new AppException("0001", String.format("参数校验失败:%s", constraintViolations.iterator().next().getMessage()));
}
}
}
4.在代码中调用工具类进行参数校验:
ValidationUtils.validate(requestDto);
以下是对hibernate-validator中部分注解进行描述:
| @AssertTrue | 用于boolean字段,该字段只能为true |
| @AssertFalse | 该字段的值只能为false |
| @CreditCardNumber | 对信用卡号进行一个大致的验证 |
| @DecimalMax | 只能小于或等于该值 |
| @DecimalMin | 只能大于或等于该值 |
| @Digits(integer=,fraction=) | 检查是否是一种数字的整数、分数,小数位数的数字 |
| 检查是否是一个有效的email地址 | |
| @Future | 检查该字段的日期是否是属于将来的日期 |
| @Length(min=,max=) | 检查所属的字段的长度是否在min和max之间,只能用于字符串 |
| @Max | 该字段的值只能小于或等于该值 |
| @Min | 该字段的值只能大于或等于该值 |
| @NotNull | 不能为null |
| @NotBlank | 不能为空,检查时会将空格忽略 |
| @NotEmpty | 不能为空,这里的空是指空字符串 |
| @Null | 检查该字段为空 |
| @Past | 检查该字段的日期是在过去 |
| @Pattern(regex=,flag=) | 被注释的元素必须符合指定的正则表达式 |
| @Range(min=,max=,message=) | 被注释的元素必须在合适的范围内 |
| @Size(min=, max=) | 检查该字段的size是否在min和max之间,可以是字符串、数组、集合、Map等 |
| @URL(protocol=,host,port) | 检查是否是一个有效的URL,如果提供了protocol,host等,则该URL还需满足提供的条件 |
| @Valid | 该注解主要用于字段为一个包含其他对象的集合或map或数组的字段,或该字段直接为一个其他对象的引用,这样在检查当前对象的同时也会检查该字段所引用的对象 |


浙公网安备 33010602011771号