您的位置:首页 > 编程语言 > Java开发

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

2012-06-21 15:36 639 查看
先定义两个注解类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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐