SpringAOP MethodInterceptor方法拦截器
来源:互联网 发布:ubuntu安装wireshark 编辑:程序博客网 时间:2024/06/04 19:40
声明:本博文用于学习总结及工作心得
在以前的工作中也使用到AOP , 比如记录日志,短信通知;所以在遇见当前的问题时, 首先想到的是使用Spring的核心AOP机制来解决问题;
其实问题处理起来很简单, 但是有一个问题就是,当前的框架已经搭建好, 已经使用在生产线上,最终要的是该功能涉及到整个项目,如果
不适用AOP机制的话,岂不是我要一个一个文件去修改,代码量大不说,并且还容易出线bug,所以想这种情况,肯定是选择AOP机制来处理
问题:在修改数据库的实体数据时, 根据操作人,来查看权限, 是否有权限修改(权限操作上实际是没问题, 主要是后期客户其它需求的权限验证)
框架:ssh2
数据库:mysql
解决方案:使用MethodInterceptor方法拦截器, 在调用Action 的update函数或者addOrUpdate函数之前进行拦截(项目中修改操作都是在Action的update或者
addOrUpdate函数中操作),从中获取需要修改的实体类,获取操作人, 最后再验证权限;但是,这样会有一个问题,前端每一个请求的参数都是不一样的,并且
实体类型都不一样,拦截到的获取不到实际的参数(实体类,操作人);
改变思路,拦截DAO层,数据库操作(当时因为设计框架时没有service层, 只能是DAO层);实际操作后, 方法拦截器拦截不到,至于原因,百度上很多,
这里就不啰嗦了;
最后只能,新添加service层, action中调用sevice的update函数,并将需要修改的对象当参数传给service,MethodInterceptor方法拦截器去拦截service,通过
MethodInvocation 获取action传递过来的实体类型, 剩下的就是一些业务逻辑了, 下面贴一下代码:
方法拦截器:UpdateInterceptor:
package com.test.utils;import com.test.bean_new.personnel.Company;import com.test.bean_new.personnel.Department;import com.test.bean_new.personnel.Employee;import com.test.bean_new.personnel.User;import com.test.dao_new.EmployeeDAO;import com.test.dao_new.UserDAO;import net.sf.json.JSONObject;import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation;import org.apache.poi.ss.formula.functions.T;import org.apache.struts2.ServletActionContext;import org.hibernate.*;import javax.servlet.http.HttpServletResponse;import java.beans.PropertyDescriptor;import java.io.IOException;import java.io.PrintWriter;import java.io.Serializable;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.net.URLDecoder;import java.util.ArrayList;import java.util.List;import java.util.Map;/** * Created by Administrator on 2017/4/13 0013. */public class UpdateInterceptor implements MethodInterceptor { private SessionFactory sessionFactory; @Override public Object invoke(MethodInvocation invo) throws Throwable { Object[] args = invo.getArguments(); Method method = invo.getMethod(); if (!"update".equals(method.getName()) && !"addOrUpdate".equals(method.getName())) { Object obj = invo.proceed(); return obj; } try { UserDAO userDAO = (UserDAO) Utils.getBean("userDAO"); Object obj = ServletActionContext.getRequest().getSession().getAttribute("userSession"); String personName = ""; if (obj != null) { Object personNameObj = ((Map) obj).get("userName"); if (personNameObj != null) { personName = personNameObj.toString(); } } User user = userDAO.getUser(personName); if(user.getUserGroup() == 3){ obj = invo.proceed(); return obj; } if(null != args && args.length>0){ obj = args[0]; Class cls = obj.getClass(); Field[] fields = cls.getDeclaredFields(); Field field = null; //获取Id String fieldName=""; for(int i=0 ; i< fields.length; i++){ field = fields[i]; fieldName = field.toString().substring(field.toString().lastIndexOf(" ")); fieldName = fieldName.substring(fieldName.lastIndexOf(".")+1); if("id".equals(fieldName)){ break; } } boolean flag = checkPermissionByUpdateUser(field, obj, cls, user); if(!flag){ //返回权限不足给前端 JSONObject json = new JSONObject(); json.put("success", false); json.put("msg", "权限不足"); HttpServletResponse response = ServletActionContext.getResponse(); PrintWriter writer = null; response.setCharacterEncoding("UTF-8"); response.setContentType("text/html; charset=utf-8"); try { writer = response.getWriter(); writer.print(json); } catch (IOException e) { e.printStackTrace(); } finally { if (writer != null) writer.close(); } return null; } Object reObj =invo.proceed(); return reObj; } } catch (Exception e) { e.printStackTrace(); } return args; } /** * * @param field obj中的属性Id字段 * @param obj 需要保存的实例对象 * @return * @throws Exception */ private boolean checkPermissionByUpdateUser(Field field, Object obj, Class cls, User user) throws Exception { String objName = cls.toString(); String clsName = objName.substring(objName.lastIndexOf(".")+1); PropertyDescriptor pd = new PropertyDescriptor(field.getName(), obj.getClass()); Method getMethod = pd.getReadMethod(); Object o = getMethod.invoke(obj);//执行get方法返回一个Object //获取记录操作人字段名称 String updateUser = getUpdateUser(cls); if(null == updateUser || "".equals(updateUser)) return false; //查询数据库中真实的updateUser String sql = "SELECT "+updateUser+" FROM "+clsName + " where id = "+(int)o; updateUser = (String) getRealEntity(sql); EmployeeDAO employeeDAO = (EmployeeDAO) Utils.getBean("employeeDAO"); Employee employee = employeeDAO.getEmployeeByName(updateUser); if(null != employee){//根据公司来做检查 Department department = employee.getDepartment(); Company company = department.getCompany(); employee = employeeDAO.get(user.getEmployeeId()); Company company2 = null; if(null != employee){ department = employee.getDepartment(); company2 = department.getCompany(); } if(company.getId().equals(company2.getId())){ return true; } } return false; } private Object getRealEntity(String sql){ Session session = sessionFactory.openSession(); List<T> entities = new ArrayList<T>(); try { Query query = createSQLQuery(session, sql); entities = query.list(); } catch (Exception e) { e.printStackTrace(); session.close(); } finally { if (session.isOpen()) { session.close(); } } if(null != entities && !entities.isEmpty()) return entities.get(0); return null; } private String getUpdateUser(Class cls) throws Exception { Field[] fields = cls.getDeclaredFields(); //获取Id for(int i=0 ; i< fields.length; i++){ Field field = fields[i]; switch (field.getName()){ case "updateOperator": return "updateOperator"; case "updateUser": return "updateUser"; case "operatorName": return "operatorName"; case "operateMan": return "operateMan"; case "operateman": return "operateman"; case "operatePerson": return "operatePerson"; } } return ""; } public SQLQuery createSQLQuery(Session session, String sql, final Object... values) { SQLQuery query = session.createSQLQuery(sql); if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } return query; } private String getParamStr(String param) { String resultStr = ""; if (null != ServletActionContext.getRequest().getParameter(param)) { try { resultStr = URLDecoder.decode(ServletActionContext.getRequest().getParameter(param), "utf-8"); } catch (Exception e) { e.printStackTrace(); } } return resultStr; } public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; }}
package com.test.service.fixasset;import com.test.bean_new.finance.Fixasset;import com.test.dao_new.FixassetDAO;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;/** * Created by Administrator on 2017/4/15 0015. */@Component //自动扫描注解spring beanpublic class FixassetService { @Autowired//自动装配 private FixassetDAO fixassetDAO; public boolean update(Fixasset fixasset){ boolean flag = fixassetDAO.addOrUpdate(fixasset); return flag; } public FixassetDAO getFixassetDAO() { return fixassetDAO; } public void setFixassetDAO(FixassetDAO fixassetDAO) { this.fixassetDAO = fixassetDAO; }}
<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><import resource="classpath:applicationContext-*.xml" /><context:component-scan base-package="com.test.service.*"></context:component-scan><!--数据库配置信息--><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><list><!-- 标准配置 --><value>classpath:db.properties</value></list></property></bean><!-- <bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"lazy-init="true" /> --><!--dataSource--><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="${jdbc.driver}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></bean><!--数据库事务--><bean id="txManage" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean><tx:advice id="txAdvice" transaction-manager="txManage"><tx:attributes><tx:method name="insert*" propagation="REQUIRED" /><tx:method name="get*" read-only="true" /><tx:method name="find*" read-only="true" /><tx:method name="search*" read-only="true" /><tx:method name="query*" read-only="true" /><tx:method name="add*" propagation="REQUIRED" /><tx:method name="del*" propagation="REQUIRED" /><tx:method name="update*" propagation="REQUIRED" /><tx:method name="do*" propagation="REQUIRED" /><tx:method name="save*" propagation="REQUIRED" /><tx:method name="saveOrUpdate*" propagation="REQUIRED" /><tx:method name="*" propagation="REQUIRED" read-only="true" /></tx:attributes></tx:advice><aop:config><aop:pointcut expression="execution(* com.test.dao_new*.*(..))" id="serviceMethod" /><aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" /></aop:config><!--sessionFactory--><bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"><property name="dataSource" ref="dataSource" /><property name="hibernateProperties"><props><prop key="hibernate.connection.autocommit">true</prop><prop key="myeclipse.connection.profile">MySQL</prop><!--<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>--><prop key="hibernate.dialect">com.test.dao_new.MySQLLocalDialect</prop><!--<prop key="hibernate.hbm2ddl.auto">create</prop>--><prop key="hibernate.hbm2ddl.auto">update</prop><prop key="hibernate.myeclipse.connection.profile">true</prop><!-- <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> --></props></property><property name="mappingLocations"><list><!-- 省略--></list></property></bean><!--MethodInterceptor--><bean id="myInterceptor" class="com.test.utils.UpdateInterceptor" abstract="false" lazy-init="false" autowire="default"><property name="sessionFactory" ref="sessionFactory" /></bean><bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"><property name="beanNames"><list><value>fixassetService</value><!-- 添加需要拦截的service bean--></list></property><property name="interceptorNames"><list><value>myInterceptor</value></list></property></bean></beans>
- SpringAOP MethodInterceptor方法拦截器
- Spring方法拦截器MethodInterceptor
- Spring方法拦截器MethodInterceptor
- Spring方法拦截器MethodInterceptor
- Spring方法拦截器MethodInterceptor
- Spring方法拦截器MethodInterceptor
- Spring方法拦截器MethodInterceptor
- 方法拦截器(MethodInterceptor)使用
- spring 方法拦截器 MethodInterceptor接口
- MethodInterceptor拦截器
- Spring方法拦截器MethodInterceptor和AOP统一处理log
- Spring AOP及MethodInterceptor拦截器实现方法拦截以及切入点函数阻止执行
- spring 拦截器 MethodInterceptor 配置 config aop
- spring 拦截器 MethodInterceptor 配置 config aop
- spring 拦截器 MethodInterceptor 配置 config aop
- spring aop 拦截器 MethodInterceptor 配置
- SpringAOP动态拦截方法并重写
- MethodInterceptor拦截器 加注解精准拦截method
- Android WebView 与 原生的交互
- pat 1116. Come on! Let's C
- 利用javascript在网页实现八数码启发式A*算法动画
- 去除危险字符的filter(包含转为中文)
- Web安全相关(三):开放重定向(Open Redirection)
- SpringAOP MethodInterceptor方法拦截器
- 南阳理工ACM 题目2 括号配对问题
- Hibernate关联关系
- 判断素数,并输出多少以内的所有素数
- Web安全相关(二):跨站请求伪造(CSRF/XSRF)
- android错误笔记----嵌套listview显示只有一行
- 能力方程式----职场指明灯
- 小白学习笔记-Day01-W3School
- 浅谈RAID写惩罚(Write Penalty)与IOPS计算