一、先来说说在项目中遇到的问题:由于需要对用户权限进行控制,在控制过程中采用的Sturts2的拦截器:为了获得session,我在拦截器类上实现了SessionAware(愚蠢的错误),才开始是想方便,结果怎么也得不到session,相关代码如下:
package edu.cqupt.iactg.helper; import java.util.Map; import org.apache.commons.fileupload.servlet.ServletRequestContext; import org.apache.struts2.interceptor.SessionAware; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; import edu.cqupt.iactg.action.UserAction; public class UserInterceptor implements Interceptor ,SessionAware{ private Map<String ,Object> session=null;//获得session private Map<String,Object> session3=null; public static final String LOGIN="index";//全局返回值 public void destroy() { System.out.println("拦截器销毁"); } public void init() { System.out.println("拦截器加载"); } public String intercept(ActionInvocation actionInvocation) throws Exception { System.out.println("进入拦截器"); //如果访问的是登陆acton则不需要对其拦截 if(actionInvocation.getAction() instanceof UserAction){ System.out.println("Useraction========================="); return actionInvocation.invoke();//执行其他的拦截器 } session = actionInvocation.getInvocationContext().getSession(); // 从Invocation得到session对象 Map<String,Object> session2=ActionContext.getContext().getSession(); System.out.println(session+"actionInvocation的session"); System.out.println(session2+"ActionCOntext的session"); System.out.println(session3+"注入的session"); String user=(String) session.get("username");//得到session中的值 //如果存在该用户,放行 System.out.println(user); if(user!=null&&!user.isEmpty()){ System.out.println("存在该用户"); return actionInvocation.invoke(); }else{ //如果不存在该用户 System.out.println("不岑在该用户"); return LOGIN;//跳转到登陆页面 } } public void setSession(Map<String, Object> arg0) { this.session3=arg0; System.out.println("注入session3"); } }
<interceptor-stack name="defaultStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="i18n"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="debugging"/> <interceptor-ref name="profiling"/> <interceptor-ref name="scopedModelDriven"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> </interceptor-stack> <!-- The completeStack is here for backwards compatibility for applications that still refer to the defaultStack by the old name --> <interceptor-stack name="completeStack"> <interceptor-ref name="defaultStack"/> </interceptor-stack> <!-- Sample execute and wait stack. Note: execAndWait should always be the *last* interceptor. --> <interceptor-stack name="executeAndWaitStack"> <interceptor-ref name="execAndWait"> <param name="excludeMethods">input,back,cancel</param> </interceptor-ref> <interceptor-ref name="defaultStack"/> <interceptor-ref name="execAndWait"> <param name="excludeMethods">input,back,cancel</param> </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="defaultStack"/>大家可以发现,Struts2已经帮我们做好了一个默认的拦截器,里面的功能大多了!大家不难发现里面有诸如modelDriven,fileupload等大家经常用到的东西。
public abstract class AbstractInterceptor implements Interceptor { public void init() { } public void destroy() { } public abstract String intercept(ActionInvocation invocation) throws Exception; }
public abstract class AbstractInterceptor implements Interceptor { public void init() { } public void destroy() { } public abstract String intercept(ActionInvocation invocation) throws Exception; }
package edu.cqupt.iactg.helper import java.util.Map; import org.apache.commons.fileupload.servlet.ServletRequestContext; import org.apache.struts2.interceptor.SessionAware; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; import edu.cqupt.iactg.action.UserAction; public class UserInterceptor implements Interceptor { private Map<String ,Object> session=null;//获得session public static final String LOGIN="index";//全局返回值 public void destroy() { System.out.println("拦截器销毁"); } public void init() { System.out.println("拦截器加载"); } public String intercept(ActionInvocation actionInvocation) throws Exception { System.out.println("进入拦截器"); //如果访问的是登陆acton则不需要对其拦截 if(actionInvocation.getAction() instanceof UserAction){ return actionInvocation.invoke();//执行其他的拦截器 } session = actionInvocation.getInvocationContext().getSession(); // 从Invocation得到session对象 String user=(String) session.get("username");//得到session中的值 //如果存在该用户,放行 System.out.println(user); if(user!=null&&!user.isEmpty()){ System.out.println("存在该用户"); return actionInvocation.invoke(); }else{ //如果不存在该用户 System.out.println("不岑在该用户"); return LOGIN;//跳转到登陆页面 } } }
<package name="basic" abstract="true" extends="json-default"> <!-- 定义自己的拦截器 --> <interceptors> <!-- z指定改拦截器的位置 --> <interceptor name="userInterceptor" class="edu.cqupt.iactg.helper.UserInterceptor"></interceptor> <!-- 指定拦截器栈 --> <interceptor-stack name="myStack"> <interceptor-ref name="defaultStack"></interceptor-ref><!-- Struts2自己提供的默认拦截器 --> <interceptor-ref name="userInterceptor"></interceptor-ref><!-- 我们自己定义的拦截器 --> </interceptor-stack> </interceptors> <!-- <default-interceptor-ref name="myStack"></default-interceptor-ref> --><!--设置为默认拦截器 --> <global-results> <result name="ERROR" type="redirectAction">disparter/error</result> <result name="index" type="redirect">/</result><!-- 登陆界面地址 --> </global-results> <!-- 异常处理 --> <global-exception-mappings> <exception-mapping result="ERROR" exception="java.lang.Exception"/> </global-exception-mappings> </package>
<package name="disparter" namespace="/disparter" extends="basic"> <action name="main"> <interceptor-ref name="myStack"></interceptor-ref> <result>/jsp/index_main.jsp</result> </action> <action name="home"> <interceptor-ref name="myStack"></interceptor-ref> <result>/jsp/home.jsp</result> </action> <action name="index"> <result>index.jsp</result> </action> <action name="error"> <result>/jsp/error.html</result> </action> </package>
过滤器,是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符
拦截器,是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
拦截器与过滤器的区别 :
执行顺序 :过滤前 - 拦截前 - Action处理 - 拦截后 - 过滤后。个人认为过滤是一个横向的过程,首先把客户端提交的内容进行过滤(例如未登录用户不能访问内部页面的处理);过滤通过后,拦截器将检查用户提交数据的验证,做一些前期的数据处理,接着把处理后的数据发给对应的Action;Action处理完成返回后,拦截器还可以做其他过程(还没想到要做啥),再向上返回到过滤器的后续操作。