使用SpringAop 验证方法参数是否合法

先定义两个注解类ValidateGroup 和 ValidateFiled

ValidateGroup .java

package com.zf.ann;

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.java

package com.zf.ann;

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 ;
	
	/**
	 * 如果参数是基本数据类型或String ,就不用指定该参数,如果参数是对象,要验证对象里面某个属性,就用该参数指定属性名
	 */
	public String filedName() default "" ;
	
	/**
	 * 正则验证
	 */
	public String regStr() default "";
	
	/**
	 * 是否能为空  , 为true表示不能为空 , false表示能够为空
	 */
	public boolean notNull() default false;
	
	/**
	 * 是否能为空  , 为true表示不能为空 , false表示能够为空
	 */
	public int maxLen() default -1 ;
	
	/**
	 * 最小长度 , 用户验证字符串
	 */
	public int minLen() default -1 ;
	
	/**
	 *最大值 ,用于验证数字类型数据
	 */
	public int maxVal() default -1 ;
	
	/**
	 *最小值 ,用于验证数值类型数据
	 */
	public int minVal() default -1 ;
	
}
注解处理类

ValidateAspectHandel.java

package com.zf.aspet;
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;

import com.zf.ann.ValidateFiled;
import com.zf.ann.ValidateGroup;
/**
 * 验证注解处理类
 * @author zhoufeng
 */
@Component
@Aspect
public class ValidateAspectHandel {

	/**
	 * 使用AOP对使用了ValidateGroup的方法进行代理校验
	 * @throws Throwable 
	 */
	@SuppressWarnings({ "finally", "rawtypes" })
	@Around("@annotation(com.zf.ann.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 ,如果是用Struts2,直接返回一个String的resutl就行了
				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的时候 可能会出现这种情况
					return null ;
				}
			}
		}
	}

	/**
	 * 验证参数是否合法
	 */
	public boolean validateFiled( ValidateFiled[] valiedatefiles , Object[] args) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException{
		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 ;
	}

	/**
	 * 根据属性名 得到该属性的getter方法名
	 */
	public String getGetterNameByFiledName(String fieldName){
		return "get" + fieldName.substring(0 ,1).toUpperCase() + fieldName.substring(1) ;
	}

	/**
	 * 根据目标方法和注解类型  得到该目标方法的指定注解
	 */
	public Annotation getAnnotationByMethod(Method method , Class annoClass){
		Annotation all[] = method.getAnnotations();
		for (Annotation annotation : all) {
			if (annotation.annotationType() == annoClass) {
				return annotation;
			}
		}
		return null;
	}

	/**
	 * 根据类和方法名得到方法
	 */
	public Method getMethodByClassAndName(Class c , String methodName){
		Method[] methods = c.getDeclaredMethods();
		for (Method method : methods) {
			if(method.getName().equals(methodName)){
				return method ;
			}
		}
		return null;
	}

}



需要验证参数的Control方法

package com.zf.service;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.zf.ann.ValidateFiled;
import com.zf.ann.ValidateGroup;
import com.zf.vo.Person;

@Controller("PersonControl")
public class PersonControl {
	
	//下面方法 ,是需要验证参数的方法
	@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("savePerson")
	public ModelAndView savePerson(Person person , String name , int age , String email){
		ModelAndView mav = new ModelAndView("/index.jsp");
		System.out.println("addPerson()方法调用成功!");
		return mav ;		//返回index.jsp视图
	}
	
}


application.xml配置



测试

package com.zf.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zf.service.PersonControl;
import com.zf.vo.Person;
public class PersonTest {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		PersonControl ps = (PersonControl) ac.getBean("PersonControl");	//测试
		ps.savePerson(new Person(3, "qqq") , "sss" , 100 , "243970446@qq.com");
	}
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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">
	<context:component-scan base-package="com.*"></context:component-scan>
	<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>


评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值