在上篇文章中我们留下了这个问题。在这里我们一点一点的解决。
问题一
由于我们写了自己的拦截器,默认的拦截器不起作用了。
解决办法一
把默认拦截器加入到配置文件中
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 开发者模式 -->
<constant name="struts.devMode" value="true"></constant>
<package name="user" extends="struts-default" namespace="/user">
<!-- 声明自己定义的拦截器,名字以及对应的java类 -->
<interceptors>
<interceptor name="myInterceptor" class="com.scx.web.intercepter.LoginIntercepter"></interceptor>
</interceptors>
<!-- 全局逻辑结果视图 -->
<global-results>
<result name="input">/login.jsp</result>
</global-results>
<!-- 用户登录的操作方法 -->
<action name="login" class="com.scx.web.action.UserAction" method="login">
<result name="success" type="redirectAction">toMain</result>
</action>
<!-- 显示主页的操作方法 -->
<action name="toMain" class="com.scx.web.action.UserAction" method="main">
<!-- 默认拦截器配置进来 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 自定义拦截器配置进来 -->
<interceptor-ref name="myInterceptor"></interceptor-ref>
<result name="success">/main.jsp</result>
</action>
<!-- 显示另一个页面的操作方法 -->
<action name="toOther" class="com.scx.web.action.UserAction" method="other">
<!-- 默认拦截器配置进来 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 自定义拦截器配置进来 -->
<interceptor-ref name="myInterceptor"></interceptor-ref>
<result name="success">/other.jsp</result>
</action>
</package>
</struts>
问题二
解决方法一中存在的问题:当有多个拦截器,多个action动作时,需要配置的地方太多。
解决办法二
抽取公共的包,把全局配置放入公共包中
每次我们在Struts.xml编写包时都会将其继承于struts-default,这是struts2核心jar包里面为我们提供的。
想去看的同学可以解压Struts2的核心包, 里面有struts-default.xml,打开就能看到,第128行。
这里的继承和javase里面的继承一样,我们当然也可以继承于自己新建的包,有个前提就是,我们新建的包一定要是抽象的,即未配置任何action动作。
一定要仔细看注释,否则可能看不懂。
简而言之就是:
- 我们新建了一个名为my-default的package 继承于struts-default
- 我们在my-default包里面配置我们的自定义拦截器栈myDefaultStack,引入自定义的拦截器和系统默认的拦截器栈
- 在action动作的包继承于my-default。在主页和其它页面的action动作里添加我们自定义的拦截器栈myDefaultStack
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 开发者模式 -->
<constant name="struts.devMode" value="true"></constant>
<package name="my-default" abstract="true" extends="struts-default">
<interceptors>
<!-- 声明自己定义的拦截器,名字以及对应的java类 -->
<interceptor name="myInterceptor" class="com.scx.web.intercepter.LoginIntercepter"></interceptor>
<!-- 自定义的拦截器栈 -->
<interceptor-stack name="myDefaultStack">
<!-- 配置自己定义的拦截器 -->
<interceptor-ref name="myInterceptor"></interceptor-ref>
<!-- 配置默认的拦截器栈 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 全局逻辑结果视图 -->
<global-results>
<result name="input">/login.jsp</result>
</global-results>
</package>
<!-- 继承于上面的my-default -->
<package name="user" extends="my-default" namespace="/user">
<!-- 用户登录的操作方法 -->
<action name="login" class="com.scx.web.action.UserAction" method="login">
<result name="success" type="redirectAction">toMain</result>
</action>
<!-- 显示主页的操作方法 -->
<action name="toMain" class="com.scx.web.action.UserAction" method="main">
<!-- 引入自定义的拦截器栈 name和上面我们自定义的拦截器栈名相对应-->
<interceptor-ref name="myDefaultStack"></interceptor-ref>
<result name="success">/main.jsp</result>
</action>
<!-- 显示另一个页面的操作方法 -->
<action name="toOther" class="com.scx.web.action.UserAction" method="other">
<!-- 引入自定义的拦截器栈 name和上面我们自定义的拦截器栈名相对应-->
<interceptor-ref name="myDefaultStack"></interceptor-ref>
<result name="success">/other.jsp</result>
</action>
</package>
</struts>
这样似乎解决了很多拦截器的问题,但是还没解决很多action动作仍然需要配置的问题,到底能不能不配置呢?
问题三
解决方法二还没解决很多action动作仍然需要配置的问题,到底能不能不配置呢?
解决办法三
思路:我们在设置【开发模式】时,覆盖掉了一个default.properties中的常量,能不能把struts-default.xml中的默认拦截器栈的设置给覆盖掉呢?答案是可以的。
同样也是在struts-default.xml中可以找到这行代码
- 在my-default包里面设置默认的拦截器栈
- 删除解决方法二action里面配置的自定义拦截器栈
配置后的代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 开发者模式 -->
<constant name="struts.devMode" value="true"></constant>
<package name="my-default" abstract="true" extends="struts-default">
<interceptors>
<!-- 声明自己定义的拦截器,名字以及对应的java类 -->
<interceptor name="myInterceptor" class="com.scx.web.intercepter.LoginIntercepter"></interceptor>
<!-- 自定义的拦截器栈 -->
<interceptor-stack name="myDefaultStack">
<!-- 配置自己定义的拦截器 -->
<interceptor-ref name="myInterceptor"></interceptor-ref>
<!-- 配置默认的拦截器栈 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 设置默认拦截器 -->
<default-interceptor-ref name="myDefaultStack"/>
<!-- 全局逻辑结果视图 -->
<global-results>
<result name="input">/login.jsp</result>
</global-results>
</package>
<!-- 继承于上面的my-default -->
<package name="user" extends="my-default" namespace="/user">
<!-- 用户登录的操作方法 -->
<action name="login" class="com.scx.web.action.UserAction" method="login">
<result name="success" type="redirectAction">toMain</result>
</action>
<!-- 显示主页的操作方法 -->
<action name="toMain" class="com.scx.web.action.UserAction" method="main">
<result name="success">/main.jsp</result>
</action>
<!-- 显示另一个页面的操作方法 -->
<action name="toOther" class="com.scx.web.action.UserAction" method="other">
<result name="success">/other.jsp</result>
</action>
</package>
</struts>
这样配置 似乎我们完成了我们的目标,无论有多少个自定义拦截器都可以配置到my-default包里面,无论都多少个action只要它继承于my-default就可以。可是你有没有发现,这样连我们的登录页面也被拦截了。
问题真是一个接着一个出现 。累觉不爱啊
问题四
解决方法三把我们的登录界面都被拦截了
解决办法四
需要通过AbstractInterceptor类的子类入手,通过查看发现,该类还有一个子类是抽象的
- excludeMethods配置哪些动作方法不拦截
-
includeMethods配置那些动作方法拦截
我们都可以在struts.xml中通过注入的方式进行配置。根据自己的需求为不同的参数注入。
所以我们在自定义拦截器时,还可以继承MethodFilterInterceptor并且重写doIntercept方法。 在struts.xml配置的部分代码如下运行似乎没有问题。
还是有个问题 不知道大家有没有发现
我们是在my-default里面配置哪些方法需要拦截,哪些方法不需要拦截。但是在没有写动作类和动作方法之前,不确定方法名叫什么。
问题五
我们在声明时配置了哪些方法需要拦截,哪些方法不需要拦截。但是在没有写动作类和动作方法之前,不确定方法名叫什么。
解决办法五
我们可以在需要使用拦截器的时候给它注入参数。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 开发者模式 -->
<constant name="struts.devMode" value="true"></constant>
<package name="my-default" abstract="true" extends="struts-default">
<interceptors>
<!-- 声明自己定义的拦截器,名字以及对应的java类 -->
<interceptor name="myInterceptor" class="com.scx.web.intercepter.LoginIntercepter"></interceptor>
<!-- 自定义的拦截器栈 -->
<interceptor-stack name="myDefaultStack">
<!-- 配置自己定义的拦截器 -->
<interceptor-ref name="myInterceptor"></interceptor-ref>
<!-- 配置默认的拦截器栈 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 设置默认拦截器 -->
<default-interceptor-ref name="myDefaultStack"/>
<!-- 全局逻辑结果视图 -->
<global-results>
<result name="input">/login.jsp</result>
</global-results>
</package>
<!-- 继承于上面的my-default -->
<package name="user" extends="my-default" namespace="/user">
<!-- 用户登录的操作方法 -->
<action name="login" class="com.scx.web.action.UserAction" method="login">
<interceptor-ref name="myDefaultStack">
<!-- 在使用拦截器时给拦截器注入参数 -->
<param name="myInteceptor.excludeMethods">login</param>
</interceptor-ref>
<result name="success" type="redirectAction">toMain</result>
</action>
<!-- 显示主页的操作方法 -->
<action name="toMain" class="com.scx.web.action.UserAction" method="main">
<result name="success">/main.jsp</result>
</action>
<!-- 显示另一个页面的操作方法 -->
<action name="toOther" class="com.scx.web.action.UserAction" method="other">
<result name="success">/other.jsp</result>
</action>
</package>
</struts>