通过 Spring AOP 验证方法的参数是否合法

来源:互联网 发布:中国谁靠卖域名发财 编辑:程序博客网 时间:2024/05/22 13:52

最近项目中需要在后台验证前台传来的参数是否合法,在网上搜索了一些 针对方法参数 的验证方式,发现通过 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";
 }
1 0
原创粉丝点击