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

 

先定义两个注解类ValidateGroup 和 ValidateFiled

ValidateGroup .java

  1. package com.zf.ann;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. @Retention(RetentionPolicy.RUNTIME)
  7. @Target(ElementType.METHOD)
  8. public @interface ValidateGroup {
  9. public ValidateFiled[] fileds() ;
  10. }

ValidateFiled.java

  1. package com.zf.ann;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. @Retention(RetentionPolicy.RUNTIME)
  7. @Target(ElementType.METHOD)
  8. public @interface ValidateFiled {
  9. /**
  10. * 参数索引位置
  11. */
  12. public int index() default -1 ;
  13. /**
  14. * 如果参数是基本数据类型或String ,就不用指定该参数,如果参数是对象,要验证对象里面某个属性,就用该参数指定属性名
  15. */
  16. public String filedName() default "" ;
  17. /**
  18. * 正则验证
  19. */
  20. public String regStr() default "";
  21. /**
  22. * 是否能为空  , 为true表示不能为空 , false表示能够为空
  23. */
  24. public boolean notNull() default false;
  25. /**
  26. * 是否能为空  , 为true表示不能为空 , false表示能够为空
  27. */
  28. public int maxLen() default -1 ;
  29. /**
  30. * 最小长度 , 用户验证字符串
  31. */
  32. public int minLen() default -1 ;
  33. /**
  34. *最大值 ,用于验证数字类型数据
  35. */
  36. public int maxVal() default -1 ;
  37. /**
  38. *最小值 ,用于验证数值类型数据
  39. */
  40. public int minVal() default -1 ;
  41. }

注解处理类

ValidateAspectHandel.java

  1. package com.zf.aspet;
  2. import java.lang.annotation.Annotation;
  3. import java.lang.reflect.InvocationTargetException;
  4. import java.lang.reflect.Method;
  5. import org.aspectj.lang.ProceedingJoinPoint;
  6. import org.aspectj.lang.annotation.Around;
  7. import org.aspectj.lang.annotation.Aspect;
  8. import org.springframework.stereotype.Component;
  9. import org.springframework.web.servlet.ModelAndView;
  10. import com.zf.ann.ValidateFiled;
  11. import com.zf.ann.ValidateGroup;
  12. /**
  13. * 验证注解处理类
  14. * @author zhoufeng
  15. */
  16. @Component
  17. @Aspect
  18. public class ValidateAspectHandel {
  19. /**
  20. * 使用AOP对使用了ValidateGroup的方法进行代理校验
  21. * @throws Throwable
  22. */
  23. @SuppressWarnings({ "finally", "rawtypes" })
  24. @Around("@annotation(com.zf.ann.ValidateGroup)")
  25. public Object validateAround(ProceedingJoinPoint joinPoint) throws Throwable  {
  26. boolean flag = false ;
  27. ValidateGroup an = null;
  28. Object[] args =  null ;
  29. Method method = null;
  30. Object target = null ;
  31. String methodName = null;
  32. try{
  33. methodName = joinPoint.getSignature().getName();
  34. target = joinPoint.getTarget();
  35. method = getMethodByClassAndName(target.getClass(), methodName);    //得到拦截的方法
  36. args = joinPoint.getArgs();     //方法的参数
  37. an = (ValidateGroup)getAnnotationByMethod(method ,ValidateGroup.class );
  38. flag = validateFiled(an.fileds() , args);
  39. }catch(Exception e){
  40. flag = false;
  41. }finally{
  42. if(flag){
  43. System.out.println("验证通过");
  44. return joinPoint.proceed();
  45. }else{  //这里使用了Spring MVC ,所有返回值应该为Strng或ModelAndView ,如果是用Struts2,直接返回一个String的resutl就行了
  46. System.out.println("验证未通过");
  47. Class returnType = method.getReturnType();  //得到方法返回值类型
  48. if(returnType == String.class){ //如果返回值为Stirng
  49. return "/error.jsp";        //返回错误页面
  50. }else if(returnType == ModelAndView.class){
  51. return new ModelAndView("/error.jsp");//返回错误页面
  52. }else{  //当使用Ajax的时候 可能会出现这种情况
  53. return null ;
  54. }
  55. }
  56. }
  57. }
  58. /**
  59. * 验证参数是否合法
  60. */
  61. public boolean validateFiled( ValidateFiled[] valiedatefiles , Object[] args) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException{
  62. for (ValidateFiled validateFiled : valiedatefiles) {
  63. Object arg = null;
  64. if("".equals(validateFiled.filedName()) ){
  65. arg = args[validateFiled.index()];
  66. }else{
  67. arg = getFieldByObjectAndFileName(args[validateFiled.index()] ,
  68. validateFiled.filedName() );
  69. }
  70. if(validateFiled.notNull()){        //判断参数是否为空
  71. if(arg == null )
  72. return false;
  73. }else{      //如果该参数能够为空,并且当参数为空时,就不用判断后面的了 ,直接返回true
  74. if(arg == null )
  75. return true;
  76. }
  77. if(validateFiled.maxLen() > 0){      //判断字符串最大长度
  78. if(((String)arg).length() > validateFiled.maxLen())
  79. return false;
  80. }
  81. if(validateFiled.minLen() > 0){      //判断字符串最小长度
  82. if(((String)arg).length() < validateFiled.minLen())
  83. return false;
  84. }
  85. if(validateFiled.maxVal() != -1){   //判断数值最大值
  86. if( (Integer)arg > validateFiled.maxVal())
  87. return false;
  88. }
  89. if(validateFiled.minVal() != -1){   //判断数值最小值
  90. if((Integer)arg < validateFiled.minVal())
  91. return false;
  92. }
  93. if(!"".equals(validateFiled.regStr())){ //判断正则
  94. if(arg instanceof String){
  95. if(!((String)arg).matches(validateFiled.regStr()))
  96. return false;
  97. }else{
  98. return false;
  99. }
  100. }
  101. }
  102. return true;
  103. }
  104. /**
  105. * 根据对象和属性名得到 属性
  106. */
  107. public Object getFieldByObjectAndFileName(Object targetObj , String fileName) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
  108. String tmp[] = fileName.split("\\.");
  109. Object arg = targetObj ;
  110. for (int i = 0; i < tmp.length; i++) {
  111. Method methdo = arg.getClass().
  112. getMethod(getGetterNameByFiledName(tmp[i]));
  113. arg = methdo.invoke(arg);
  114. }
  115. return arg ;
  116. }
  117. /**
  118. * 根据属性名 得到该属性的getter方法名
  119. */
  120. public String getGetterNameByFiledName(String fieldName){
  121. return "get" + fieldName.substring(0 ,1).toUpperCase() + fieldName.substring(1) ;
  122. }
  123. /**
  124. * 根据目标方法和注解类型  得到该目标方法的指定注解
  125. */
  126. public Annotation getAnnotationByMethod(Method method , Class annoClass){
  127. Annotation all[] = method.getAnnotations();
  128. for (Annotation annotation : all) {
  129. if (annotation.annotationType() == annoClass) {
  130. return annotation;
  131. }
  132. }
  133. return null;
  134. }
  135. /**
  136. * 根据类和方法名得到方法
  137. */
  138. public Method getMethodByClassAndName(Class c , String methodName){
  139. Method[] methods = c.getDeclaredMethods();
  140. for (Method method : methods) {
  141. if(method.getName().equals(methodName)){
  142. return method ;
  143. }
  144. }
  145. return null;
  146. }
  147. }

需要验证参数的Control方法

  1. package com.zf.service;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.servlet.ModelAndView;
  5. import com.zf.ann.ValidateFiled;
  6. import com.zf.ann.ValidateGroup;
  7. import com.zf.vo.Person;
  8. @Controller("PersonControl")
  9. public class PersonControl {
  10. //下面方法 ,是需要验证参数的方法
  11. @ValidateGroup(fileds = {
  12. //index=0 表示下面方法的第一个参数,也就是person  nutNull=true 表示不能为空
  13. @ValidateFiled(index=0 , notNull=true ) ,
  14. //index=0 表示第一个参数  filedName表示该参数的一个属性 ,也就是person.id 最小值为3 也就是 person.id 最小值为3
  15. @ValidateFiled(index=0 , notNull=true , filedName="id" , minVal = 3) ,
  16. //表示第一个参数的name 也就是person.name属性最大长度为10,最小长度为3
  17. @ValidateFiled(index=0 , notNull=true , filedName="name" , maxLen = 10 , minLen = 3 ) ,
  18. //index=1 表示第二个参数最大长度为5,最小长度为2
  19. @ValidateFiled(index=1 , notNull=true , maxLen = 5 , minLen = 2 ) ,
  20. @ValidateFiled(index=2 , notNull=true , maxVal = 100 , minVal = 18),
  21. @ValidateFiled(index=3 , notNull=false , regStr= "^\\w+@\\w+\\.com$" )
  22. })
  23. @RequestMapping("savePerson")
  24. public ModelAndView savePerson(Person person , String name , int age , String email){
  25. ModelAndView mav = new ModelAndView("/index.jsp");
  26. System.out.println("addPerson()方法调用成功!");
  27. return mav ;        //返回index.jsp视图
  28. }
  29. }

application.xml配置

测试

  1. package com.zf.test;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. import com.zf.service.PersonControl;
  5. import com.zf.vo.Person;
  6. public class PersonTest {
  7. public static void main(String[] args) {
  8. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  9. PersonControl ps = (PersonControl) ac.getBean("PersonControl"); //测试
  10. ps.savePerson(new Person(3, "qqq") , "sss" , 100 , "243970446@qq.com");
  11. }
  12. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
  4. xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  8. http://www.springframework.org/schema/tx
  9. http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
  10. http://www.springframework.org/schema/aop
  11. http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
  12. http://www.springframework.org/schema/context
  13. http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  14. <context:component-scan base-package="com.*"></context:component-scan>
  15. <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
  16. </beans>

Spring AOP实现 Bean字段合法性校验的更多相关文章

  1. Spring AOP学习笔记01:AOP概述

    1. AOP概述 软件开发一直在寻求更加高效.更易维护甚至更易扩展的方式.为了提高开发效率,我们对开发使用的语言进行抽象,走过了从汇编时代到现在各种高级语言繁盛之时期:为了便于维护和扩展,我们对某些相 ...

  2. Spring AOP简述

    使用面想对象(Object-Oriented Programming,OOP)包含一些弊端,当需要为多个不具有继承关系的对象引入公共行为时,例如日志,安全检测等.我们只有在每个对象中引入公共行为,这样 ...

  3. Spring Aop实例

    一.XML方式 1. TestAspect:切面类 package com.spring.aop; import org.aspectj.lang.JoinPoint; import org.aspe ...

  4. Spring AOP实现方式四之注入式AspectJ切面【附源码】

    现在我们要讲的是第四种AOP实现之注入式AspectJ切面 通过简单的配置就可以实现AOP了. 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.ao ...

  5. Spring AOP实现方式三【附源码】

    注解AOP实现 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.aop; /** * 谈恋爱接口 * * @author Administrator ...

  6. Spring AOP实现方式二【附源码】

    自动代理模式[和我们说的方式一 配置 和 测试调用不一样哦~~~]  纯POJO切面 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.aop; /* ...

  7. Spring AOP实现方式一【附源码】

    基本代理模式  纯POJO切面 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.aop; /** * 谈恋爱接口 * * @author Admin ...

  8. Spring Aop重要概念介绍及应用实例结合分析

    转自:http://bbs.csdn.net/topics/390811099 此前对于AOP的使用仅限于声明式事务,除此之外在实际开发中也没有遇到过与之相关的问题.最近项目中遇到了以下几点需求,仔细 ...

  9. Spring AOP应用实例demo

    AOP(Aspect-Oriented Programming.面向方面编程).能够说是OOP(Object-OrientedPrograming.面向对象编程)的补充和完好.OOP引入封装.继承和多 ...

随机推荐

  1. 非递归并查集——zoj4109

    卡常卡的我难受 非递归并查集好像写起来常数小一点 int F[maxn]; int Find(int x){ int r = x; while (F[r] != r)r = F[r]; int i = ...

  2. zabbix4.0添加磁盘io监控

    agent服务器端的操作 1.设置zabbix-agent端的配置文件 找到agent端配置文件的位置,本例agent端的配置文件路径在/usr/local/etc/zabbix下 首先:在主配置文件 ...

  3. C++—模板(1)模板与函数模板

    1.引入 如何编写一个通用加法函数?第一个方法是使用函数重载, 针对每个所需相同行为的不同类型重新实现这个函数.C++的这种编程机制给编程者极大的方便,不需要为功能相似.参数不同的函数选用不同的函数名 ...

  4. C#应用编程小例子-02-窗体最大化和最小化窗体大小

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. python基础知识练习题(二)

    1. 有两个列表 l1 = [11, 22, 33] l2 = [22, 33, 44] a.获取内容相同的元素列表 li = []l1 = [11, 22, 33] l2 = [22, 33, 44 ...

  6. Codeforces 741B Arpa's weak amphitheater and Mehrdad's valuable Hoses (并查集+分组背包)

    <题目链接> 题目大意: 就是有n个人,每个人都有一个体积和一个价值.这些人之间有有些人之间是朋友,所有具有朋友关系的人构成一组.现在要在这些组中至多选一个人或者这一组的人都选,在总容量为 ...

  7. 基于centos7系统部署cobbler

    准备环境和下载cobbler 一,系统准备 虚拟机下要添加两个网卡.一个仅主机对内提供cobbler服务,一个桥接用来通外网 系统版本为:CentOS 7.5 内网ip :169.254.1.6  # ...

  8. unzip解压失败

    [root@localhost soft]# unzip QY.zip Archive: QY.zip End-of-central-directory signature not found. Ei ...

  9. Unity Rain Ai 插件基本使用(二)

    前言 在前面的教程中我们已经基本实现了路径导航和障碍物规避. 但是这样我们并没有让我们的角色学会思考,他只是机械的去完成一些步骤,这并不能体现Rain插件的智能. 一个角色他应该有多个不同的状态,待机 ...

  10. Python数据可视化编程实战pdf

    Python数据可视化编程实战(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1vAvKwCry4P4QeofW-RqZ_A 提取码:9pcd 复制这段内容后打开百度 ...