Spring AOP实现 Bean字段合法性校验
使用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>
 
Spring AOP实现 Bean字段合法性校验的更多相关文章
- Spring AOP学习笔记01:AOP概述
		
1. AOP概述 软件开发一直在寻求更加高效.更易维护甚至更易扩展的方式.为了提高开发效率,我们对开发使用的语言进行抽象,走过了从汇编时代到现在各种高级语言繁盛之时期:为了便于维护和扩展,我们对某些相 ...
 - Spring AOP简述
		
使用面想对象(Object-Oriented Programming,OOP)包含一些弊端,当需要为多个不具有继承关系的对象引入公共行为时,例如日志,安全检测等.我们只有在每个对象中引入公共行为,这样 ...
 - Spring Aop实例
		
一.XML方式 1. TestAspect:切面类 package com.spring.aop; import org.aspectj.lang.JoinPoint; import org.aspe ...
 - Spring AOP实现方式四之注入式AspectJ切面【附源码】
		
现在我们要讲的是第四种AOP实现之注入式AspectJ切面 通过简单的配置就可以实现AOP了. 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.ao ...
 - Spring AOP实现方式三【附源码】
		
注解AOP实现 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.aop; /** * 谈恋爱接口 * * @author Administrator ...
 - Spring AOP实现方式二【附源码】
		
自动代理模式[和我们说的方式一 配置 和 测试调用不一样哦~~~] 纯POJO切面 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.aop; /* ...
 - Spring AOP实现方式一【附源码】
		
基本代理模式 纯POJO切面 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.aop; /** * 谈恋爱接口 * * @author Admin ...
 - Spring Aop重要概念介绍及应用实例结合分析
		
转自:http://bbs.csdn.net/topics/390811099 此前对于AOP的使用仅限于声明式事务,除此之外在实际开发中也没有遇到过与之相关的问题.最近项目中遇到了以下几点需求,仔细 ...
 - Spring AOP应用实例demo
		
AOP(Aspect-Oriented Programming.面向方面编程).能够说是OOP(Object-OrientedPrograming.面向对象编程)的补充和完好.OOP引入封装.继承和多 ...
 
随机推荐
- P2255 [USACO14JAN]记录奥林比克
			
P2255 [USACO14JAN]记录奥林比克 题目描述 农民约翰热衷于所有寒冷天气的运动(尤其是涉及到牛的运动), 农民约翰想录下尽可能多的电视节目. 为moolympics电视时间表由N个不同的 ...
 - JavaScript ES6 新特性详解
			
JavaScript ES6 带来了新的语法和新的强大功能,使您的代码更现代,更易读 const , let and var 的区别: const , let 是 ES6 中用于声明变量的新关键字. ...
 - Scyther 论文相关资料整理
			
1.Scyther 的特点使用方法 Scyther可以提供轨迹的简单描述,方便分析协议可能出现的攻击和表现,使用Athena算法,该软件表现如下特点: 该软件有明确的终止,能工提供无限会话协议安全性的 ...
 - MySQL----下载安装
			
MySQL 的官网下载地址:http://www.mysql.com/downloads/ 注意 1. MySQL Community Server 社区版本,开源免费,但不提供官方技术支持.2. M ...
 - 学习笔记: AOP面向切面编程和C#多种实现
			
AOP:面向切面编程 编程思想 OOP:一切皆对象,对象交互组成功能,功能叠加组成模块,模块叠加组成系统 类--砖头 系统--房子 类--细胞 系统--人 ...
 - Java练习2
			
1 编写一个应用程序,模拟机动车的加速和减速功能.机动车类Vehicle的UML图如下,其中speedUp()方法实现加速功能,速度上限为240 km/h:speedDown()实现降速功能,下限为0 ...
 - [转]centos7 修改yum源为阿里源
			
centos7 修改yum源为阿里源,某下网络下速度比较快 首先是到yum源设置文件夹里 cd /etc/yum.repos.d 接着备份旧的配置文件 sudo mv CentOS-Base.repo ...
 - 大数据学习之Linux基础01
			
大数据学习之Linux基础 01:Linux简介 linux是一种自由和开放源代码的类UNIX操作系统.该操作系统的内核由林纳斯·托瓦兹 在1991年10月5日首次发布.,在加上用户空间的应用程序之后 ...
 - 【转】Apache与Tomcat有什么关系和区别
			
[原文链接:https://www.cnblogs.com/zangdalei/p/8057325.html] Apache 和 Tomcat 都是web网络服务器,两者既有联系又有区别,在进行HTM ...
 - WPF中的ObservableCollection数据绑定
			
使用时ObservableCollection必须使用get set属性声明,才能成功的绑定到控件.