学习目标:
1、掌握自定义struts2的拦截器
2、了解方法拦截器拦截器
学习过程:
struts2默认提供的拦截器已经很强大了,当然我们还是可以自定义拦截器。自定义拦截器的功能也比较简单。
一、自定义拦截器
1、实现Interceptor接口
要实现自己的拦截器,我们可以实现Interceptor接口,代码如下:
/**
* 定义实现类
*/
public class OneInterceptor implements Interceptor {
public void init() {
System.out.println("初始化方法");
}
public String intercept(ActionInvocation ai) throws Exception {
System.out.println("OneInterceptor执行之前");
String result = ai.invoke();//进入下一步骤。
System.out.println("OneInterceptor执行之后");
return result;
}
public void destroy() {
System.out.println("销毁方法");
}
}
2、配置拦截器
我们还需要在package包中配置这个拦截,这样在这个包和它的子包中就可以使用这个拦截器了。
<!-- 配置 -->
<interceptors>
<interceptor name="one" class="com.interceptor.OneInterceptor"></interceptor>
</interceptors>
3、使用拦截器
使用自定义的拦截器和使用系统的拦截器一样。我们可以在Action中使用。我们在userlist的action中配置使用测试。代码如下:
<action name="userlist" class="com.action.UserAction" method="listuser">
<result name="success">/userlist.jsp</result>
<interceptor-ref name="one"></interceptor-ref>
</action>
修改listuser的方法如下:
public String listuser() {
System.out.println("执行了Action");
users = userDao.getAll();
return SUCCESS;
}
现在打开浏览器访问一下这个Action应该,系统会抛出空指针异常,因为我们显示写了拦截器后会覆盖默认拦截器。修改action的配置如下:
<action name="userlist" class="com.action.UserAction" method="listuser">
<result name="success">/userlist.jsp</result>
<interceptor-ref name="one"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
再次访问,控制台输出如下:
OneInterceptor执行之前
执行了Action
OneInterceptor执行之后
二、拦截器的执行顺序
1、再定义一个新的拦截器
public class TwoInterceptor implements Interceptor {
public void init() {
System.out.println("初始化方法");
}
public String intercept(ActionInvocation ai) throws Exception {
System.out.println("TwoInterceptor执行之前");
String result = ai.invoke();
System.out.println("TwoInterceptor执行之后");
return result;
}
public void destroy() {
System.out.println("销毁方法");
}
}
配置代码:
<interceptors>
<interceptor name="one" class="com.interceptor.OneInterceptor"></interceptor>
<interceptor name="two" class="com.interceptor.TwoInterceptor"></interceptor>
</interceptors>
action配置代码,我们先配置one,然后在配置two,代码如下:
<action name="userlist" class="com.action.UserAction" method="listuser">
<result name="success">/userlist.jsp</result>
<interceptor-ref name="one"></interceptor-ref>
<interceptor-ref name="two"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
2、访问action
控制台输出:
OneInterceptor执行之前
TwoInterceptor执行之前
执行了Action
TwoInterceptor执行之后
OneInterceptor执行之后
可见,拦截器的配置是选配置的选执行,在action返回时顺序就会相反。
三、配置拦截器栈和默认拦截器
1、拦截器栈,我们如果一次引用多个拦截器,那么我们可以把多个拦截器或者拦截器栈封装成为一个拦截器栈。
代码如下:
<interceptors>
<interceptor name="one" class="com.interceptor.OneInterceptor"></interceptor>
<interceptor name="two" class="com.interceptor.TwoInterceptor"></interceptor>
<interceptor-stack name="oneAndTwo">
<interceptor-ref name="one"></interceptor-ref>
<interceptor-ref name="two"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
那么在使用的时候就可以只引用一个拦截器栈就可以了,修改action的配置文件。
<action name="userlist" class="com.action.UserAction" method="listuser">
<result name="success">/userlist.jsp</result>
<interceptor-ref name="oneAndTwo"></interceptor-ref>
</action>
2、如果我们在一个包里所有的action都需要使用该拦截器。那么我们可以在包中配置一个默认拦截器引用,代码如下:
<!-- 默认拦截器 这个包和它的子包 -->
<default-interceptor-ref name="oneAndTwo"></default-interceptor-ref>
3、注意struts2的配置文件是有顺序要求的,上面这个配置不能写作action配置的后面。struts2配置文件的顺序如下:
(result-types?,interceptors?,default-interceptor-ref?,default-action-ref?,default-class-ref?,global-results?,global-exception-mappings?,action*)
四、定义方法拦截器的方法
方法拦截器拦截器可以只拦截部分方法。你可以使用灵活的使用通配符,拦截你需要拦截的action的方法。 实现MethodFilterInterceptor方法。代码如下:
public class MyMethodInterceptro extends MethodFilterInterceptor{
@Override
protected String doIntercept(ActionInvocation ai) throws Exception {
System.out.println("MyMethodInterceptro方法拦截器之前");
String result=ai.invoke();
System.out.println("MyMethodInterceptro方法拦截器之后");
return result;
}
}
五、配置方法拦截器
和配置普通的拦截器不一样。在action中引用该拦截器时,我们可以定了param属性
<param name="name">方法1,方法2</param>
name一般使用excludeMethods(表示不包括的方法),includeMethods(包括的方法)两个值。如下面的代码,表示拦截addGoods方法。
<!-- 方法拦截器 -->
<interceptor-ref name="mymethod">
<!-- 定义拦截的方法 -->
<param name="includeMethods">addGoods,uselist</param>
</interceptor-ref>
不拦截就这样配置
<!-- 方法拦截器 -->
<interceptor-ref name="mymethod">
<!-- 定义拦截的方法 -->
<param name="excludeMethods">addGoods</param>
</interceptor-ref>
如果都配置了,拦截器会拦截该方法,也就是说includeMethods的优先级别比较高。还支持通配符的方法,代码如下:
<!-- 方法拦截器 -->
<interceptor-ref name="mymethod">
<!-- 定义拦截的方法 -->
<param name="includeMethods">add*</param>
</interceptor-ref>
表示拦截所有已add开头的方法。