用户工具

站点工具


分享:技术:validation:hibernate_validator

hibernate_validator

介绍

hibernate_validator是hibernate提供的参数校验框架,通过在pojo类属性上加限制注解,再通过工具类校验参数,将异常抛出。

maven引入

maven引入:pom.xml

<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-validator</artifactId>
	<version>${hibernate-validator.version}</version>
</dependency>

spring配置文件

spring配置文件,比如:application-context.xml

	<!-- 参数校验AOP begin -->
	<bean id="validateAop" class="com.gxx.record.core.ValidateAop" />
	<aop:config>
		<aop:aspect id="validateAspect" ref="validateAop">
			<aop:pointcut id="target" expression="execution(* com.gxx.record.service..*.*(..))" />
			<aop:around method="around" pointcut-ref="target" />
		</aop:aspect>
	</aop:config>
	<!-- 参数校验AOP end -->

方法注解

切面扫描方法,方法上有这个注解@Validate,才会去校验每个入参的属性

Validate.java
package com.gxx.record.core;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/** 
 * 校验参数注解
 * @author Gxx
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface Validate {
	/**
	 * 是否校验参数
	 * true才校验
	 * @return
	 */
	boolean isValidate() default false;
}

切面类

ValidateAop.java
package com.gxx.record.core;
 
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
 
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
 
import com.gxx.record.utils.ValidationUtils;
 
/**
 * 服务层AOP
 * @author Gxx
 */
public class ValidateAop {
 
	/**
	 * 日志处理器
	 */
	private final Logger logger = Logger.getLogger(ValidateAop.class);
 
	/**
	 * 方法前后操作
	 * @param pjp
	 * @return
	 * @throws Exception
	 */
	public Object around(ProceedingJoinPoint pjp) throws Throwable {
		/**
		 * 获取切面方法
		 */
		Signature sig = pjp.getSignature();
		MethodSignature msig = null;
		if (!(sig instanceof MethodSignature)) {
			throw new IllegalArgumentException("该注解只能用于方法");
		}
		msig = (MethodSignature) sig;
		Object target = pjp.getTarget();
		Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
 
		/**
		 * 判断是否加注解@LogMethodTime 和 是否落地
		 */
		boolean isValidateAnnotation = currentMethod.isAnnotationPresent(Validate.class);//是否加注解@Validate
		/**
		 * 判断是否加注解@Validate
		 */
		if(isValidateAnnotation) {
			Annotation p = currentMethod.getAnnotation(Validate.class);
 
			Method m = p.getClass().getDeclaredMethod("isValidate", null);
			boolean isValidate = (Boolean) m.invoke(p, null);
			/**
			 * 是否需要校验
			 */
			if(isValidate) {
				/**
				 * 参数校验
				 */
				Object[] args = pjp.getArgs();
				if(null != args && args.length > 0) {
					for(Object arg : args) {
						ValidationUtils.validate(arg);
					}
				}
			}
		}
 
		/**
		 * 执行方法
		 */
		return pjp.proceed();
	}
}

校验工具类

ValidationUtils.java
package com.gxx.record.utils;
 
import java.util.Set;
 
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
 
import org.hibernate.validator.HibernateValidator;
 
/**
 * 校验工具类
 * @author Gxx
 */
public class ValidationUtils {
    /**
     * 使用hibernate的注解来进行验证
     */
    private static Validator validator = Validation.byProvider(HibernateValidator.class)
    		.configure().failFast(true).buildValidatorFactory().getValidator();
 
    /**
     * 校验
     * @param obj
     */
    public static <T> void validate(T obj) {
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj);
        /**
         * 抛出检验异常
         */
        if (constraintViolations.size() > 0) {
            throw new RuntimeException(String.format("参数校验失败:%s", constraintViolations.iterator().next().getMessage()));
        }
    }
}

请求入口类

UserController.java
package com.gxx.record.web.user;
 
import javax.servlet.http.HttpServletRequest;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.gxx.record.dto.UserDto;
import com.gxx.record.service.UserService;
 
/**
 * <dl>
 *    <dt><b>Title:</b></dt>
 *    <dd>
 *    	none
 *    </dd>
 *    <dt><b>Description:用户控制器</b></dt>
 *    <dd>
 *    	<p>none
 *    </dd>
 * </dl>
 *
 * @author Administrator
 * @version 1.0, 2017年12月14日
 * @since record
 *
 */
@Controller
@RequestMapping("/user/")
public class UserController {
 
	@Autowired
	private UserService userService;
 
	/**
	 * 校验
	 * @param request
	 * @param userDto
	 * @return
	 */
	@RequestMapping(value = "/validate", produces="application/json")
	public @ResponseBody String validate(HttpServletRequest request, UserDto userDto) {
		return userService.validate(userDto);
	}
}

pojo类

UserDto.java
package com.gxx.record.dto;
 
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
 
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import org.hibernate.validator.constraints.URL;
 
/**
 * <dl>
 *    <dt><b>Title:</b></dt>
 *    <dd>
 *    	用户传输对象
 *    </dd>
 *    <dt><b>Description:</b></dt>
 *    <dd>
 *    	<p>none
 *    </dd>
 * </dl>
 *
 * @author Administrator
 * @version 1.0, 2017年12月14日
 * @since record
 *
 */
public class UserDto {
 
	@NotNull(message = "昵称不能为空")
	private String validNick;
 
	@NotEmpty(message = "姓名不能为空字符串")
	private String validName;
 
	@AssertTrue(message = "钱必须是真的")
	private boolean validMoney;
 
	@Max(value=10, message = "数字不能大于10")
	@Min(value=5, message = "数字不能小于5")
	private int validNumber;
 
	@NotEmpty(message = "字符串不能为空字符串")//如果不配置NotEmpty而且为空,则不校验Length
	@Length(min=5, max=10, message = "字符串长度有误")
	private String validString;
 
	@NotEmpty(message = "email不能为空字符串")//如果不配置NotEmpty而且为空,则不校验Email
	@Email(message = "email格式有误")
	private String validEmail;
 
	@NotEmpty(message = "url不能为空字符串")//如果不配置NotEmpty而且为空,则不校验URL
	@URL(message = "url格式有误")
	private String validUrl;
 
	public String getValidName() {
		return validName;
	}
	public void setValidName(String validName) {
		this.validName = validName;
	}
	public boolean isValidMoney() {
		return validMoney;
	}
	public void setValidMoney(boolean validMoney) {
		this.validMoney = validMoney;
	}
	public String getValidEmail() {
		return validEmail;
	}
	public void setValidEmail(String validEmail) {
		this.validEmail = validEmail;
	}
	public String getValidString() {
		return validString;
	}
	public void setValidString(String validString) {
		this.validString = validString;
	}
	public int getValidNumber() {
		return validNumber;
	}
	public void setValidNumber(int validNumber) {
		this.validNumber = validNumber;
	}
	public String getValidUrl() {
		return validUrl;
	}
	public void setValidUrl(String validUrl) {
		this.validUrl = validUrl;
	}
	public String getValidNick() {
		return validNick;
	}
	public void setValidNick(String validNick) {
		this.validNick = validNick;
	}
}

服务接口

UserService.java
package com.gxx.record.service;
 
import com.gxx.record.dto.UserDto;
 
/**
 * <dl>
 *    <dt><b>Title:</b></dt>
 *    <dd>
 *    	用户服务接口
 *    </dd>
 *    <dt><b>Description:</b></dt>
 *    <dd>
 *    	<p>none
 *    </dd>
 * </dl>
 *
 * @author Administrator
 * @version 1.0, 2017年12月14日
 * @since record
 *
 */
public interface UserService {
 
	/**
	 * 校验接口
	 * @param userDto
	 * @return
	 */
	public String validate(UserDto userDto);
}

服务实现类

UserServiceImpl.java
package com.gxx.record.service.impl;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import com.gxx.record.base.dao.UserMapper;
import com.gxx.record.base.vo.User;
import com.gxx.record.core.Datasource;
import com.gxx.record.core.Validate;
import com.gxx.record.dto.UserDto;
import com.gxx.record.service.UserService;
 
/**
 * <dl>
 *    <dt><b>Title:</b></dt>
 *    <dd>
 *    	用户服务实现类
 *    </dd>
 *    <dt><b>Description:</b></dt>
 *    <dd>
 *    	<p>none
 *    </dd>
 * </dl>
 *
 * @author Administrator
 * @version 1.0, 2017年12月14日
 * @since record
 *
 */
@Service("userService")
public class UserServiceImpl implements UserService {
 
	/**
	 * 校验接口
	 * @param userDto
	 * @return
	 */
	@Validate(isValidate = true)
	public String validate(UserDto userDto) {
		return "OK";
	}
}

测试

http://localhost:8080/record/user/validate.htm?validName=gxx&validMoney=true&validNumber=10&validString=abcab&validEmail=419066357@qq.com&validUrl=http://www.baidu.com

参数校验失败:昵称不能为空

http://localhost:8080/record/user/validate.htm?validNick=&validName=&validMoney=true&validNumber=10&validString=abcab&validEmail=419066357@qq.com&validUrl=http://www.baidu.com

参数校验失败:姓名不能为空字符串

http://localhost:8080/record/user/validate.htm?validNick=&validName=gxx&validMoney=false&validNumber=10&validString=abcab&validEmail=419066357@qq.com&validUrl=http://www.baidu.com

参数校验失败:钱必须是真的

http://localhost:8080/record/user/validate.htm?validNick=&validName=gxx&validMoney=true&validNumber=4&validString=abcab&validEmail=419066357@qq.com&validUrl=http://www.baidu.com

参数校验失败:数字不能小于5

http://localhost:8080/record/user/validate.htm?validNick=&validName=gxx&validMoney=true&validNumber=11&validString=abcab&validEmail=419066357@qq.com&validUrl=http://www.baidu.com

参数校验失败:数字不能大于10

http://localhost:8080/record/user/validate.htm?validNick=&validName=gxx&validMoney=true&validNumber=10&validString=abc&validEmail=419066357@qq.com&validUrl=http://www.baidu.com

参数校验失败:字符串长度有误

http://localhost:8080/record/user/validate.htm?validNick=&validName=gxx&validMoney=true&validNumber=10&validString=abcab&validEmail=ABC&validUrl=http://www.baidu.com

参数校验失败:email格式有误

http://localhost:8080/record/user/validate.htm?validNick=&validName=gxx&validMoney=true&validNumber=10&validString=abcab&validEmail=419066357@qq.com&validUrl=abc

参数校验失败:url格式有误

http://localhost:8080/record/user/validate.htm?validNick=&validName=gxx&validMoney=true&validNumber=10&validString=abcab&validEmail=419066357@qq.com&validUrl=http://www.baidu.com

参数校验通过,返回OK

注解列表

注解 含义
@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或数组的字段,或该字段直接为一个其他对象的引用,这样在检查当前对象的同时也会检查该字段所引用的对象
分享/技术/validation/hibernate_validator.txt · 最后更改: 2017/12/14 18:45 由 gxx