Live2D

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 检查是否是一个有效的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或数组的字段,或该字段直接为一个其他对象的引用,这样在检查当前对象的同时也会检查该字段所引用的对象
posted @ 2021-03-02 15:57  ΜΑΗΑΙΓΞ小白  阅读(519)  评论(0)    收藏  举报