Struts2 拦截器中实现对数据进行数据库操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xj80231314/article/details/51782872

功能需求说明:

        用拦截器的方式,拦截以.action结尾的类,同时记录访问的action名称、action的包路径、action后面带的参数、操作者的ID、操作者的姓名、等其他数据。

吐槽点:

1.当我拿到这个需求的时候,直接懵逼了,用日志的方式不是更好么,干嘛要用这个拦截器呢?项目经理脑袋秀逗了啊?当我把这个想法说了之后,得到的是项目经理一句“那种做法太low了”,我想请问low么?应该不low吧,你们觉得呢?

2.好久没有接触SSH,更何况拦截器以前就用得很少,没办法,只有现学现用,好吧,接着就百度,这里是最坑逼的,玛蛋,一搜一大把都是拿登录来做实例,特别让人想吐槽的就是代码和描述什么的都是千篇一律,还都说自己的是原创,wqnmlgb,好意思么?

下面就正式开始,直接上代码,不废话半天:

1.新建一个类来继承AbstractInterceptor,然后重写他的方法:

public class ActionInterceptor extends AbstractInterceptor{
	/**
	 * 数据库表POJO {@link com.mavis.demeter.bean.interceptor.Tracker}的业务逻辑层。
	 * @since 4.4
	 */
	private ITrackerService trackerService;
        // 提供getter/setter
	public ITrackerService getTrackerService() {
		return trackerService;
	}
	public void setTrackerService(ITrackerService trackerService) {
		this.trackerService = trackerService;
	}
	
	public String intercept(ActionInvocation invocation) throws Exception {
		// 在拦截器触发之前,需要把Spring中的bean实例取出来,
		// 这样在最后才能把拦截到的数据通过方法保存到数据库中
		ServletContext application = ServletActionContext.getServletContext();  
		WebApplicationContext ctx = 
			WebApplicationContextUtils.getWebApplicationContext(application);
		
		// 从ApplicationContext中取得定义在Spring中的bean实例
		this.trackerService = (ITrackerService)ctx.getBean("TrackerService");
		
                // 获取拦截到的action名称
		ActionContext ctxs = invocation.getInvocationContext();  
		String actionName = ctxs.getName().toString();
		Tracker tt = new Tracker();
		tt.setActionName(actionName);
		
		// 获取拦截到的action参数
		Map<String, String> param = new HashMap<String, String>();
                HttpServletRequest request = ServletActionContext.getRequest();
                   Map<String, String[]> params = request.getParameterMap();
                   for (String key : params.keySet()) {
                      String[] values = params.get(key);
                      for (int i = 0; i < values.length; i++) {
                         param.put(key, values[i]);
                      }
                   }
                tt.setActionParameters(param.toString());
		
		// 获取拦截到的action所在的包路径
		String actionPakeages = invocation.getAction().toString();
		// 截取完整的包名
		String[] split = actionPakeages.split("@", 9);
		String actionPakeage = split[0].toString();
		tt.setActionPakeage(actionPakeage);
		
		// 获取拦截到的组织机构ID
		Orgnization orgnization = (Orgnization)ctxs.getSession().get(Constant.SESSION_ORGNIZATION);
		if(orgnization != null){
			tt.setOrganizationId(orgnization.getOrgnizationId());
		}
		// 获取拦截到的员工ID
		Staff staff = (Staff)ctxs.getSession().get(Constant.SESSION_STAFF);
		if(staff != null){
			tt.setStaffId(staff.getStaffId());
			tt.setStaffName(staff.getShownName());
		}
		tt.setTrackerTime(new Date());
		// 把拦截到的数据保存到数据库中
		this.trackerService.save(tt);
		
		return invocation.invoke();
	}
	
	
}
第二步:配置struts2
    <!-- 新增拦截器配置 -->
    <package name="myInterceptor" extends="struts-default">
        <interceptors>
            <!-- 定义权限控制拦截器 -->
            <interceptor name="authority" class="com.mavis.hermes.interceptor.ActionInterceptor"/>(name随便取,class就是你拦截器所在的地方,引入进来)
            <!-- 定义一个包含权限控制的拦截器栈 -->
            <interceptor-stack name="mydefault">
                <!-- 默认拦截器 -->
                <interceptor-ref name="defaultStack" />
                <!-- 自定义拦截器 -->
                <interceptor-ref name="authority" />
            </interceptor-stack>
        </interceptors>
        <!-- 定义默认拦截器 -->
        <default-interceptor-ref name="mydefault" />
        
    </package>
    <!-- 拦截器配置结束 -->
针对第二步想多BB两句:

1.先看看那个登录权限拦截器的实现原理,里面有很清晰的解释什么的默认拦截器,什么是自定义拦截器,他们执行的顺序和各自的运用时机。

2.别一上来就copy代码,先看懂再自己写,代码要自己敲出来才是自己的。

第三步:在struts.xml中,凡是配置了action类的pakeage中,都继承你自己定义的这个拦截器,代码如下:

<package name="proscenium" extends="myInterceptor" namespace="/">

第四步:最重要的东西

                // 在拦截器触发之前,需要把Spring中的bean实例取出来,
		// 这样在最后才能把拦截到的数据通过方法保存到数据库中
		ServletContext application = ServletActionContext.getServletContext();  
		WebApplicationContext ctx = 
			WebApplicationContextUtils.getWebApplicationContext(application);
		
		// 从ApplicationContext中取得定义在Spring中的bean实例
		this.trackerService = (ITrackerService)ctx.getBean("TrackerService");

就是这个上面几句话,憋我了一天,玛蛋,好不容易想起的,都怪自己,把很多以前的都忘记了,好记性不如烂笔头啊,这也是写这篇博客的初衷吧。

解释一下:

在拦截器中,传统的注入和new都是不可行的,至于具体什么原因,我忘记了,好像跟什么反射机制有关,

第一句:

ServletContext application = ServletActionContext.getServletContext(); 

利用ServletActionContext获取到ServletContext

第二句:

WebApplicationContext ctx = 
			WebApplicationContextUtils.getWebApplicationContext(application);
利用WebApplicationContextUtils中的getWebApplicationContext(application)方法,把ServletContext丢进去,用于获取WebApplicationContext

第三句:

通过WebApplicationContext就可以获取到Spring中配置的bean

this.trackerService = (ITrackerService)ctx.getBean("TrackerService");

通过以上步骤,你就可以顺利的把POJO的Service注入到拦截器中了,这样你就可以在拦截器中进行数据的CRUD了。


猜你喜欢

转载自blog.csdn.net/xj80231314/article/details/51782872