拦截器:
Struts2的大多数核心功能都是通过拦截器实现的。拦截器之所以称之为“拦截器”,是因为它可以在执行Action之前或之后拦截下用户请求,执行一些操作,以增强Action方法的功能。
Struts2内置了35种拦截器,每个拦截器完成相对独立的功能,多个拦截器的组合体称为拦截器栈。最为重要的拦截器栈是系统默认的拦截器栈DefaultStack。
通常情况下,自定义一个普通的拦截器类需要实现拦截器接口Interceptor。该接口中定义了三个方法:
public void init(); 拦截器实例被创建之前被调用
public void destory(); 拦截器实例被销毁之前被调用
public String intercept(ActionInvocation invocation) throws Exception:该方法在Action执行之前被调用,拦截器的附加功能在该方法中实现。执行参数invocation的invoke()方法,就是调用Action方法去执行。
常用的拦截器(在struts-default.xml中可查):
自定义权限拦截器:
拦截器类的代码如下:
package com.tongji.interceptors; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; public class PermissionInterceptor implements Interceptor { private static final long serialVersionUID = 2730133447721824856L; @Override public void destroy() { } @Override public void init() { } @Override public String intercept(ActionInvocation invocation) throws Exception { String user = (String) ActionContext.getContext().getApplication().get("user"); System.out.println(user); if (!"qjj".equals(user)) { System.out.println("bad"); return "fail"; } //调用Action方法 return invocation.invoke(); } }
注册拦截器的方式(注意拦截器是方法级的):
(1)单个拦截器分别注册的方式:
<?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> <package name="demo" namespace="/test" extends="struts-default"> <interceptors> <interceptor name="permissionInterceptor" class="com.tongji.interceptors.PermissionInterceptor"/> </interceptors> <action name="system" class="com.tongji.actions.SystemAction"> <result>/welcome.jsp</result> <result name="fail">/fail.jsp</result> <!-- 一旦显示的声明了action要使用拦截器,则系统默认的拦截器栈defaultStack将不再执行--> <interceptor-ref name="permissionInterceptor"/> <interceptor-ref name="defaultStack"/> </action> </package> </struts>
(2)拦截器栈的注册方式:
<?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> <package name="demo" namespace="/test" extends="struts-default"> <interceptors> <interceptor name="permissionInterceptor" class="com.tongji.interceptors.PermissionInterceptor"/> <interceptor-stack name="permissionStack"> <interceptor-ref name="permissionInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <action name="system" class="com.tongji.actions.SystemAction"> <result>/welcome.jsp</result> <result name="fail">/fail.jsp</result> <interceptor-ref name="permissionStack"/> </action> </package> </struts>
(3)默认拦截器的注册方式:
<?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> <package name="demo" namespace="/test" extends="struts-default"> <interceptors> <interceptor name="permissionInterceptor" class="com.tongji.interceptors.PermissionInterceptor"/> <interceptor-stack name="permissionStack"> <interceptor-ref name="permissionInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!-- 默认的拦截器:当前包中只要没有显示声明使用的拦截器,则就会执行该默认拦截器 --> <default-interceptor-ref name="permissionStack"></default-interceptor-ref> <action name="system" class="com.tongji.actions.SystemAction"> <result>/welcome.jsp</result> <result name="fail">/fail.jsp</result> </action> </package> </struts>
补充:
(1)方法过滤拦截器:
拦截器类代码如下(注意继承自MethodFilterInterceptor抽象类,当然这个抽象类最后也是实现Interceptor接口的):
package com.tongji.interceptors; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; public class PermissionInterceptor extends MethodFilterInterceptor{ private static final long serialVersionUID = 6243069277042908932L; @Override protected String doIntercept(ActionInvocation invocation) throws Exception { System.out.println("执行拦截器"); return invocation.invoke(); } }
方法过滤拦截器的注册方式:
<?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> <package name="demo" namespace="/test" extends="struts-default"> <interceptors> <interceptor name="permissionInterceptor" class="com.tongji.interceptors.PermissionInterceptor"> <!-- <param name="includeMethods">doFirst</param> --> <param name="excludeMethods">doSecond,doThird</param> </interceptor> <interceptor-stack name="permissionStack"> <interceptor-ref name="permissionInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <action name="some_*" class="com.tongji.actions.SomeAction" method="{1}"> <result>/welcome.jsp</result> <interceptor-ref name="permissionInterceptor" /> </action> </package> </struts>
(2)拦截器的执行顺序与注册顺序相同:
<?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> <package name="demo" namespace="/test" extends="struts-default"> <interceptors> <interceptor name="oneInterceptor" class="com.tongji.interceptors.OneInterceptor"/> <interceptor name="twoInterceptor" class="com.tongji.interceptors.TwoInterceptor"/> <!-- 拦截器的执行顺序与其注册顺序相同 --> <interceptor-stack name="myStack"> <interceptor-ref name="twoInterceptor"></interceptor-ref> <interceptor-ref name="oneInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <action name="system" class="com.tongji.actions.SystemAction"> <result>/welcome.jsp</result> <result name="fail">/fail.jsp</result> <interceptor-ref name="myStack"/> </action> </package> </struts>
先执行twoInterceptor,再执行oneInterceptor。