今天在做登陆验证的时候,对拦截器进行了一系列的优化,
首先我们得知道,当你登陆后,才能访问到购物车,我的账户的页面,不然就可以使用拦截器跳转到登录页面。这里通过查看session是否含有user的验证
public class CheckLoginInterceptor extends AbstractInterceptor{
@Override
public String intercept(ActionInvocation arg0) throws Exception {
HttpSession sesssion=ServletActionContext.getRequest().getSession();
Object obj = sesssion.getAttribute("user");
if(obj==null){
return "input";
}
String rtValue = arg0.invoke();
return rtValue;
}
}
struts.xml的配置如下.
<package name="p2" extends="struts-default">
<interceptors>声明拦截器
<interceptor name="checkLoginInterceptor" class="com.itheima.web.interceptor.CheckLoginInterceptor" />
</interceptors>
<global-results>全局结果视图
<result name="input">/login.jsp</result>数据回显的结果视图
</global-results>
用户登录时,不需要检查登录的拦截器工作
<action name="login" class="com.itheima.web.action.Demo2Action" method="login">
<result type="redirectAction">showMain</result>
</action>
前往主页的动作名称,需要检查登录的拦截器工作
<action name="showMain" class="com.itheima.web.action.Demo2Action" >
<interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
<result>/main.jsp</result>
</action>
前往另一个页面的动作名称,需要检查登录的拦截器工作
<action name="showOther" class="com.itheima.web.action.Demo2Action" >
<interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
<result>/otherpage.jsp</result>
</action>
</package>
出现的问题:由于我们写了自己的拦截器,默认的拦截器不起作用了。
第一步优化:把默认拦截器加入到配置文件中
<package name="p2" extends="struts-default">
<interceptors>
<interceptor name="checkLoginInterceptor" class="com.itheima.web.interceptor.CheckLoginInterceptor" />
</interceptors>
<global-results>
<result name="input">/login.jsp</result>
</global-results>
<action name="login" class="com.itheima.web.action.Demo2Action" method="login">
<result type="redirectAction">showMain</result>
</action>
<action name="showMain" class="com.itheima.web.action.Demo2Action" >
加入自定义拦截器,和默认的拦截器栈
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
<result>/main.jsp</result>
</action>
<action name="showOther" class="com.itheima.web.action.Demo2Action" >
加入自定义拦截器,和默认的拦截器栈
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
<result>/otherpage.jsp</result>
</action>
</package>
出现的问题:如果需要拦截的动作很多时,写起来很繁琐,代码重复冗余.
第二步优化:抽取公共的包,把全局配置放入公共包中。
<package name="mydefault" extends="struts-default">
<interceptors>
<interceptor name="CheckLoginInterceptor class="com.hei.web.interceptor.CheckLoginInterceptor"></interceptor>
<interceptor-stack name="myDefaultStack">
<interceptor-ref name="CheckLoginInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 全局结果视图 -->
<global-results>
<result name="input">/login.jsp</result>
</global-results>
</package>
<package name="p2" extends="mydefault" >
<interceptors>
<interceptor name="checkLoginInterceptor" class="com.hei.web.interceptor.CheckLoginInterceptor"></interceptor>
</interceptors>
<action name="login" class="com.hei.web.action.Demo2Action" method="login">
<result type="redirectAction">showMain</result>
</action>
<action name="showMain" class="com.hei.web.action.Demo2Action">
<interceptor-ref name="myDefaultStack"></interceptor-ref>
<result >/main.jsp</result>
<result name="input">/login.jsp</result>
</action>
<action name="showOther" class="com.hei.web.action.Demo2Action">
<interceptor-ref name="myDefaultStack"></interceptor-ref>
<result >/otherpage.jsp</result>
</action>
</package>
问题:每个动作都要下引入拦截器。能不能不写呢?
第三步优化:覆盖struts-default.xml的默认拦截器栈
struts-default.xml上面写着 <default-interceptor-ref name="defaultStack"/>
出现的问题也很明显:例如访问login.jsp时,连登陆都被拦截了。先拦截,动作方法还为Session设施user,就已经被拦截下来了.
第四步优化 :CheckLoginInterceptor继承抽象类MethodFilterInterceptor
public class CheckLoginInterceptor1 extends MethodFilterInterceptor{
@Override
protected String doIntercept(ActionInvocation arg0) throws Exception {
HttpSession sesssion=ServletActionContext.getRequest().getSession();
Object obj=sesssion.getAttribute("user");
if(obj!=null){
String rtValue=arg0.invoke();
return rtValue;
}
return "input";
}
}
然后struts.xml配置如下
<package name="p2" extends="struts-default">
<interceptors>
<interceptor name="checkLoginInterceptor1" class="com.itheima.web.interceptor.CheckLoginInterceptor1" />
<interceptor-stack name="myDefaultStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="checkLoginInterceptor1">
给自定义拦截器注入参数,告知他哪些方法不需要拦截
<param name="excludeMethods">login</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
<global-results>
<result name="input">/login.jsp</result>
</global-results>
<action name="login" class="com.itheima.web.action.Demo2Action" method="login">
<result type="redirectAction">showMain</result>
</action>
<action name="showMain" class="com.itheima.web.action.Demo2Action" >
<result>/main.jsp</result>
</action>
<action name="showOther" class="com.itheima.web.action.Demo2Action" >
<result>/otherpage.jsp</result>
</action>
</package>
出现问题:我们在声明拦截器和定义拦截器栈的时候,可能根本不知道哪些方法需要拦截,哪些不需要
第五步优化 : 在使用拦截器的时候,注入参数,告诉拦截器哪些需要拦截,哪些不需要
<package name="p2" extends="struts-default">
<interceptors>
<interceptor name="checkLoginInterceptor1" class="com.itheima.web.interceptor.CheckLoginInterceptor1" />
<interceptor-stack name="myDefaultStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="checkLoginInterceptor1"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
<global-results>
<result name="input">/login.jsp</result>
</global-results>
<action name="login" class="com.itheima.web.action.Demo2Action" method="login">
<interceptor-ref name="myDefaultStack">
<!-- 在引用自定义拦截器栈的时候,给指定的拦截器注入参数。方式就是:拦截器名称.属性名称 -->
<param name="checkLoginInterceptor1.excludeMethods">login</param>
</interceptor-ref>
<result type="redirectAction">showMain</result>
</action>
<action name="showMain" class="com.itheima.web.action.Demo2Action" >
<result>/main.jsp</result>
</action>
<action name="showOther" class="com.itheima.web.action.Demo2Action" >
<result>/otherpage.jsp</result>
</action>
</package>
在引用自定义拦截器栈的时候,给指定的拦截器注入参数的方式就是:拦截器名称.属性名称