org.hibernate
hibernate-validator
${hibernate-validator.version}
===== spring配置文件 =====
spring配置文件,比如:application-context.xml
===== 方法注解 =====
切面扫描方法,方法上有这个注解@Validate,才会去校验每个入参的属性
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;
}
===== 切面类 =====
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();
}
}
===== 校验工具类 =====
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 void validate(T obj) {
Set> constraintViolations = validator.validate(obj);
/**
* 抛出检验异常
*/
if (constraintViolations.size() > 0) {
throw new RuntimeException(String.format("参数校验失败:%s", constraintViolations.iterator().next().getMessage()));
}
}
}
===== 请求入口类 =====
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;
/**
*
* - Title:
* -
* none
*
* - Description:用户控制器
* -
*
none
*
*
*
* @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类 =====
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;
/**
*
* - Title:
* -
* 用户传输对象
*
* - Description:
* -
*
none
*
*
*
* @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;
}
}
===== 服务接口 =====
package com.gxx.record.service;
import com.gxx.record.dto.UserDto;
/**
*
* - Title:
* -
* 用户服务接口
*
* - Description:
* -
*
none
*
*
*
* @author Administrator
* @version 1.0, 2017年12月14日
* @since record
*
*/
public interface UserService {
/**
* 校验接口
* @param userDto
* @return
*/
public String validate(UserDto userDto);
}
===== 服务实现类 =====
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;
/**
*
* - Title:
* -
* 用户服务实现类
*
* - Description:
* -
*
none
*
*
*
* @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或数组的字段,或该字段直接为一个其他对象的引用,这样在检查当前对象的同时也会检查该字段所引用的对象|