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

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

2015-04-26 23:38 671 查看
先定义两个注解类ValidateGroup 和 ValidateFiled

ValidateGroup .java

[java] view
plaincopy

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

[java] view
plaincopy

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

[java] view
plaincopy

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方法

[java] view
plaincopy

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配置

测试

[html] view
plaincopy

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");

}

}

[html] view
plaincopy

<?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>



扫扫关注“茶爸爸”微信公众号



坚持最初的执着,从不曾有半点懈怠,为优秀而努力,为证明自己而活。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐