最近项目中需要在后台验证前台传来的参数是否合法,在网上搜索了一些 针对方法参数 的验证方式,发现通过 Spring AOP 去验证方法参数的方式很好用(原文地址:http://blog.csdn.net/is_zhoufeng/article/details/7683194)
1、依赖包
aspectjweaver.jar
2、验证相关类
共三个类,分别是
ValidateGroup.java | ValidateFiled.java | ValidateAspectHandel.java
ValidateGroup
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ValidateGroup {
public ValidateFiled[] fileds();
}
------------------------------------------------------------------
ValidateFiled
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ValidateFiled {
public int index() default -1;
public String filedName() default "";
public String regStr() default "";
public boolean notNull() default false;
public int maxLen() default -1;
public int minLen() default -1;
public int maxVal() default -1;
public int minVal() default -1;
}
-------------------------------------------------------------------------
验证注解处理类ValidateAspectHandel
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
@Component
@Aspect
public class ValidateAspectHandel {
@SuppressWarnings( { "finally", "unchecked" })
@Around("@annotation(com.zqvideo.util.validata.ValidateGroup)")
public Object validateAround(ProceedingJoinPoint joinPoint)
throws Throwable {
boolean flag = false;
ValidateGroup an = null;
Object[] args = null;
Method method = null;
Object target = null;
String methodName = null;
try {
methodName = joinPoint.getSignature().getName();
target = joinPoint.getTarget();
method = getMethodByClassAndName(target.getClass(), methodName); // 得到拦截的方法
args = joinPoint.getArgs(); // 方法的参数
an = (ValidateGroup) getAnnotationByMethod(method,
ValidateGroup.class);
flag = validateFiled(an.fileds(), args);
} catch (Exception e) {
flag = false;
} finally {
if (flag) {
System.out.println("验证通过");
return joinPoint.proceed();
} else { // 这里使用了Spring MVC ,所有返回值应该为Strng或ModelAndView
System.out.println("验证未通过");
Class returnType = method.getReturnType(); // 得到方法返回值类型
if (returnType == String.class) { // 如果返回值为Stirng
return "/error.jsp"; // 返回错误页面
} else if (returnType == ModelAndView.class) {
return new ModelAndView("/error.jsp");// 返回错误页面
} else { // 当使用Ajax的时候 可能会出现这种情况
System.out.println("null");
return null;
}
}
}
}
public boolean validateFiled(ValidateFiled[] valiedatefiles, Object[] args)
throws Exception {
for (ValidateFiled validateFiled : valiedatefiles) {
Object arg = null;
if ("".equals(validateFiled.filedName())) {
arg = args[validateFiled.index()];
} else {
arg = getFieldByObjectAndFileName(args[validateFiled.index()],
validateFiled.filedName());
}
if (validateFiled.notNull()) { // 判断参数是否为空
if (arg == null)
return false;
} else { // 如果该参数能够为空,并且当参数为空时,就不用判断后面的了 ,直接返回true
if (arg == null)
return true;
}
if (validateFiled.maxLen() > 0) { // 判断字符串最大长度
if (((String) arg).length() > validateFiled.maxLen())
return false;
}
if (validateFiled.minLen() > 0) { // 判断字符串最小长度
if (((String) arg).length() < validateFiled.minLen())
return false;
}
if (validateFiled.maxVal() != -1) { // 判断数值最大值
if ((Integer) arg > validateFiled.maxVal())
return false;
}
if (validateFiled.minVal() != -1) { // 判断数值最小值
if ((Integer) arg < validateFiled.minVal())
return false;
}
if (!"".equals(validateFiled.regStr())) { // 判断正则
if (arg instanceof String) {
if (!((String) arg).matches(validateFiled.regStr()))
return false;
} else {
return false;
}
}
}
return true;
}
public Object getFieldByObjectAndFileName(Object targetObj, String fileName)
throws SecurityException, NoSuchMethodException,
IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
String tmp[] = fileName.split("\\.");
Object arg = targetObj;
for (int i = 0; i < tmp.length; i++) {
Method methdo = arg.getClass().getMethod(
getGetterNameByFiledName(tmp[i]));
arg = methdo.invoke(arg);
}
return arg;
}
public String getGetterNameByFiledName(String fieldName) {
return "get" + fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
}
@SuppressWarnings("unchecked")
public Annotation getAnnotationByMethod(Method method, Class annoClass) {
Annotation all[] = method.getAnnotations();
for (Annotation annotation : all) {
if (annotation.annotationType() == annoClass) {
return annotation;
}
}
return null;
}
@SuppressWarnings("unchecked")
public Method getMethodByClassAndName(Class c, String methodName) {
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals(methodName)) {
return method;
}
}
return null;
}
}
---------------------------------------------------------------------------
3、xml文件配置
http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
---------------------------------------------------------------------------------
4、在Controller中的使用方法
//下面方法 ,是需要验证参数的方法
@ValidateGroup(fileds = {
//index=0 表示下面方法的第一个参数,也就是person nutNull=true 表示不能为空
@ValidateFiled(index=0 , notNull=true ) ,
//index=0 表示第一个参数 filedName表示该参数的一个属性 ,也就是person.id 最小值为3 也就是 person.id 最小值为3
@ValidateFiled(index=0 , notNull=true , filedName="id" , minVal = 3) ,
//表示第一个参数的name 也就是person.name属性最大长度为10,最小长度为3
@ValidateFiled(index=0 , notNull=true , filedName="name" , maxLen = 10 , minLen = 3 ) ,
//index=1 表示第二个参数最大长度为5,最小长度为2
@ValidateFiled(index=1 , notNull=true , maxLen = 5 , minLen = 2 ) ,
@ValidateFiled(index=2 , notNull=true , maxVal = 100 , minVal = 18),
@ValidateFiled(index=3 , notNull=false , regStr= "^\\w+@\\w+\\.com$" )
})
@RequestMapping("/action")
public String checkLogin(String email, String username) {
System.out.println("eamil:
" + email);
return "main";
}