- 浏览: 519271 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (278)
- java (41)
- 设计模式 (4)
- sql (10)
- webservice (2)
- spring (9)
- struts (6)
- struts2 (32)
- hibernate (27)
- Struts_hibernate_Spring整合 (4)
- Velocity (1)
- Servlet (9)
- JSP (6)
- javascript (19)
- jquery (10)
- ajax (4)
- html、xml (3)
- JDBC (2)
- JDK (6)
- mysql (2)
- oracle (11)
- SqlServer (1)
- DB2 (4)
- tool (7)
- linux (5)
- UML (1)
- eclipse (8)
- 执行文件 (1)
- 应用服务器 (4)
- 代码重构 (1)
- 日本語 (19)
- 交规 (1)
- office (9)
- firefox (1)
- net (1)
- 测试 (1)
- temp (6)
- 对日外包 (1)
- windows (1)
- 版本控制 (1)
- android (2)
- 项目管理 (1)
最新评论
四、 开发自己的拦截器
Struts 2 框架提供了许多拦截器,这些内建拦截器实现了 struts 2 的大部分功能。但还有一些系统逻辑相关的通用功能,则需要通过自定义拦截器来实现,比如我们可以开放自己的拦截器来完成权限控制,日志记录等。Struts 2 的拦截器系统是如此的简单、易用。
4.1 实现拦截器类
如果用户要开发自己的拦截器,应该实现 com.opensymphony.xwork2.interceptor.Interceptor 接口,该接口定义如下:
package com.opensymphony.xwork2.interceptor; import com.opensymphony.xwork2.ActionInvocation; import java.io.Serializable; public interface Interceptor extends Serializable { /** * Called to let an interceptor clean up any resources it has allocated. */ void destroy(); /** * Called after an interceptor is created, but before any requests are processed using * {@link #intercept(com.opensymphony.xwork2.ActionInvocation) intercept} , giving * the Interceptor a chance to initialize any needed resources. */ void init(); /** * Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the * request by the {@link ActionInvocation} or to short-circuit the processing and just return a String return code. * * @param invocation the action invocation * @return the return code, either returned from {@link ActionInvocation#invoke()}, or from the interceptor itself. * @throws Exception any system-level error, as defined in {@link com.opensymphony.xwork2.Action#execute()}. */ String intercept(ActionInvocation invocation) throws Exception; }
上面接口包含 3 个方法:
● init()
: 在该拦截器被实例化之后,在该拦截器执行拦截之前,系统将回调该方法。对于每个拦截器而言,其 init()
方法只能执行一次。因此,该方法的方法体主要用于初始化资源,例如数据库连接等。
● destroy()
: 在拦截器实例被销毁之前,系统将回调该拦截器的 destroy
方法,一般用于销毁在 init()
方法里打开的资源
● intercept(ActionInvocation invocation) : 该方法是用户需要实现的拦截动作。就像 Action 的 execute() 一样,intercept 方法会返回一个字符串作为逻辑视图。如果该方法直接返回一个字符串,系统将会跳转到该逻辑视图对应的实际视图资源,不会调用被拦截的 Action 。 该方法的 ActionInvocation 参数包含了被拦截的 Action 的引用,可以通过调用该参数的 invoke 方法,将控制权转给下一个拦截器,或者转给 Action 的 execute() 方法
除此之外,Struts 2 还提供了一个 AbstractInterceptor 类 ,该类提供了一个 init 和 destroy 方法的空实现,如果拦截器不需要打开资源,则可以无需实现这 2 个方法。可见,用继承 AbstractInterceptor 类来实现自定义拦截器会更加简单:
package com.opensymphony.xwork2.interceptor; import com.opensymphony.xwork2.ActionInvocation; public abstract class AbstractInterceptor implements Interceptor { /** * Does nothing */ public void init() { } /** * Does nothing */ public void destroy() { } /** * Override to handle interception */ public abstract String intercept(ActionInvocation invocation) throws Exception; }
下面实现了一个简单的拦截器:
SimpleInterceptor
package js.a; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; import java.util.*; public class SimpleInterceptor extends AbstractInterceptor { // 简单拦截器的名字 private String name; // 为该简单拦截器设置名字的setter方法 public void setName(String name) { this.name = name; } public String intercept(ActionInvocation invocation) throws Exception { // 取得被拦截的Action实例 LoginAction action = (LoginAction) invocation.getAction(); // 打印执行开始的实现 System.out.println(name + " 拦截器的动作---------" + "开始执行登录Action的时间为:" + new Date()); // 取得开始执行Action的时间 long start = System.currentTimeMillis(); // 执行该拦截器的后一个拦截器 // 如果该拦截器后没有其他拦截器,则直接执行Action的execute方法 String result = invocation.invoke(); // 打印执行结束的时间 System.out.println(name + " 拦截器的动作---------" + "执行完登录Action的时间为:" + new Date()); long end = System.currentTimeMillis(); System.out.println(name + " 拦截器的动作---------" + "执行完该Action的事件为" + (end - start) + "毫秒"); return result; } }
ActionInvocation 参数可以获得被拦截的 Action 实例,一旦取得了 Action 实例,几乎获得了全部的控制权: 可以实现将 HTTP 请求中的参数解析出来,设置成 Action 的属性(这是系统 params 拦截器干的事情);也可以直接将 HTTP 请求中的 HttpServletRequest 实例和 HttpServleResponse 实例传给 Action (这是 servletConfig 拦截器干的事情),也可以实现应用相关的逻辑
LoginAction
package js.a; import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport { private String username; private String password; public void setUsername(String username) { this.username = username; } public String getUsername() { return username; } public void setPassword(String password) { this.password = password; } public String getPassword() { return password; } public String execute() throws Exception { System.out.println("进入execute方法执行体.........."); Thread.sleep(1500); if (getUsername().equals("crazyit") && getPassword().equals("leegang")) { return SUCCESS; } else { return ERROR; } } }
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.2.dtd"> <struts> <constant name="struts.custom.i18n.resources" value="messageResource"/> <constant name="struts.i18n.encoding" value="GBK"/> <include file="struts_1.xml"/> </struts>
struts_1.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.2.dtd"> <struts> <constant name="struts.custom.i18n.resources" value="messageResource"/> <constant name="struts.i18n.encoding" value="GBK"/> <package name="js.a" extends="struts-default" namespace="/10"> <!-- 应用所需使用的拦截器都在该元素下配置 --> <interceptors> <!-- 配置mysimple拦截器 --> <interceptor name="mysimple" class="js.a.SimpleInterceptor"> <!-- 为拦截器指定参数值 --> <param name="name">简单拦截器</param> </interceptor> </interceptors> <action name="login" class="js.a.LoginAction"> <result name="error">/10/error.jsp</result> <result name="success">/10/welcome.jsp</result> <!-- 拦截器一般配置在result元素之后! --> <!-- 配置系统的默认拦截器 --> <interceptor-ref name="defaultStack"/> <!-- 应用自定义的mysimple拦截器 --> <interceptor-ref name="mysimple"> <param name="name">改名后的拦截器</param> </interceptor-ref> </action> <action name=""> <result>.</result> </action> </package> </struts>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>struts2</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
login.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <%@taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>登录页面</title> </head> <body> <form action="login.action" method="post"> <table align="center"> <caption><h3>用户登录</h3></caption> <tr> <td>用户名:<input type="text" name="username"/></td> </tr> <tr> <td>密码:<input type="text" name="password"/></td> </tr> <tr align="center"> <td><input type="submit" value="登录"/> <input type="reset" value="重填" /></td> </tr> </table> </form> </body> </html>
error.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>错误页面</title> </head> <body> 您不能登录! </body> </html>
welcome.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>成功页面</title> </head> <body> 您已经登录! </body> </html>
index.jsp
<s:a href="" onclick="newWin('10/login.jsp');" cssStyle="cursor: hand;">login.jsp</s:a>
4.2 使用拦截器
以下所有代码都基于 4.1
使用拦截器需要 2 个步骤:
① 通过 <interceptor ../> 元素来定义拦截器
② 通过 <interceptor-ref ../> 元素来使用拦截器
看 4.1
中的
struts_1.xml
注意: 如果为 Action 指定了一个拦截器,则系统默认的拦截器栈将会失去作用。为了继续使用默认拦截器,所以上面配置文件中手动应用了默认拦截器。
4.3 拦截器和 Struts 2 插件的关系
扩展 Struts 2 的重要方式 : 插件,通过使用插件可以极好地扩充 Struts 2 的功能,在 Struts 2 项目的目录里,可以看到大量名为 struts2-xxx-plugin-2.2.jar 的文件,这些文件都是 Struts 2 的插件文件
Struts 2 的拦截器可用于完成各种细粒度的通用 “小功能” ,当我们需要为 Struts 2 扩展新功能时,也可能需要增加新的通用功能,这时候就需要开发自己的拦截器
当开发者开发了自己的拦截器之后,还必须配置拦截器,通常我们不可能修改 Struts 2 的 struts-default.xml ,而通用功能的拦截器也不应该在应用相关的 struts.xml 文件中配置。这就需要在 Struts 2 插件的 struts-plugin.xml 文件中配置拦截器了
例如: struts2-rest-plugin-2.2.1.jar 文件,包含了一个 struts-plugin.xml 文件:
struts-plugin.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <bean type="com.opensymphony.xwork2.ActionProxyFactory" name="rest" class="org.apache.struts2.rest.RestActionProxyFactory" /> <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="rest" class="org.apache.struts2.rest.RestActionMapper" /> <bean type="org.apache.struts2.rest.ContentTypeHandlerManager" class="org.apache.struts2.rest.DefaultContentTypeHandlerManager" /> <bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="xml" class="org.apache.struts2.rest.handler.XStreamHandler" /> <bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="json" class="org.apache.struts2.rest.handler.JsonLibHandler" /> <bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="html" class="org.apache.struts2.rest.handler.HtmlHandler" /> <bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="x-www-form-urlencoded" class="org.apache.struts2.rest.handler.FormUrlEncodedHandler" /> <bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="multipart/form-data" class="org.apache.struts2.rest.handler.MultipartFormDataHandler" /> <constant name="struts.actionProxyFactory" value="rest" /> <constant name="struts.rest.defaultExtension" value="xhtml" /> <constant name="struts.mapper.class" value="rest" /> <constant name="struts.mapper.idParameterName" value="id" /> <constant name="struts.action.extension" value="xhtml,,xml,json" /> <package name="rest-default" extends="struts-default"> <result-types> <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"> <param name="statusCode">303</param> </result-type> <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"> <param name="statusCode">303</param> </result-type> </result-types> <interceptors> <!-- 配置 Struts 2 REST 插件的拦截器 --> <interceptor name="rest" class="org.apache.struts2.rest.ContentTypeInterceptor"/> <interceptor name="restWorkflow" class="org.apache.struts2.rest.RestWorkflowInterceptor"/> <interceptor name="messages" class="org.apache.struts2.interceptor.MessageStoreInterceptor" /> <interceptor-stack name="restDefaultStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="messages"> <param name="operationMode">AUTOMATIC</param> </interceptor-ref> <interceptor-ref name="prepare"/> <interceptor-ref name="i18n"/> <interceptor-ref name="chain"/> <interceptor-ref name="debugging"/> <interceptor-ref name="profiling"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="scopedModelDriven"/> <interceptor-ref name="modelDriven"> <param name="refreshModelBeforeResult">true</param> </interceptor-ref> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*</param> </interceptor-ref> <interceptor-ref name="rest" /> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse,index,show,edit,editNew</param> </interceptor-ref> <interceptor-ref name="restWorkflow"> <param name="excludeMethods">input,back,cancel,browse,index,show,edit,editNew</param> </interceptor-ref> </interceptor-stack> </interceptors> <!-- 配置默认的拦截器栈引用 --> <default-interceptor-ref name="restDefaultStack"/> <default-class-ref class="org.apache.struts2.rest.RestActionSupport"/> </package> </struts>
通过上面配置文件可以看出 : 当需要为 Struts 2 扩展新功能时, Struts 2 插件是外在组织形式,而新增的拦截器则用于完成通用的核心功能,而 Struts 2 插件则负责组织这些新增的拦截器
五、 深入拦截器编程
拦截器的配置离不开 <interceptor .../> <interceptor-ref .../> <interceptor-stack .../> ,但对于拦截器的深入编程方面,还有一些值得注意的地方
5.1 拦截方法的拦截器
在默认情况下,如果为某个 Action 定义了拦截器,则这个拦截器会拦截该 Action 内的所有方法。但在某些情况下,我们不想拦截所有方法,只需要拦截指定方法,此时,就需要使用 Struts 2 拦截器的方法过滤特性
为了实现方法过滤特性, 需要使用一个 MethodFilterInterceptor 类,该类是 AbstractInterceptor 类的子类。如果用户需要自己实现的拦截器支持方法过滤特性,则应该继承 MethodFilterInterceptor 类
MethodFilterInterceptor 类重写了 AbstractInterceptor 类的 intercept(ActionInvocation invocation) ,但提供了一个 doIntercept(ActionInvocation invocation) 抽象方法。 MethodFilterInterceptor 的 intercept 已经实现了对 Action 的拦截行为(只实现了方法过滤的逻辑),但真正的拦截逻辑还需要开发者提供,也就是通过回调 doIntercept 方法实现。 因此用户应该重写 doIntercept(ActionInvocation invocation)
例如 :
MyFilterInterceptor
package js.a; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; import java.util.*; //方法过滤的拦截器,应该继承MethodFilterInterceptor抽象类 public class MyFilterInterceptor extends MethodFilterInterceptor { // 简单拦截器的名字 private String name; // 为该简单拦截器设置名字的setter方法 public void setName(String name) { this.name = name; } // 重写doIntercept方法,实现对Action的拦截逻辑 public String doIntercept(ActionInvocation invocation) throws Exception { // 取得被拦截的Action实例 LoginActionMy action = (LoginActionMy) invocation.getAction(); // 打印执行开始的时间 System.out.println(name + " 拦截器的动作---------" + "开始执行登录Action的时间为:" + new Date()); // 取得开始执行Action的时间 long start = System.currentTimeMillis(); // 执行该拦截器的后一个拦截器,或者直接指定Action的execute方法 String result = invocation.invoke(); // 打印执行结束的时间 System.out.println(name + " 拦截器的动作---------" + "执行完登录Action的时间为:" + new Date()); long end = System.currentTimeMillis(); // 打印执行该Action所花费的时间 System.out.println(name + " 拦截器的动作---------" + "执行完该Action的事件为" + (end - start) + "毫秒"); return result; } }
方法过滤的拦截器与实现普通拦截器并没有太大区别,只要注意 2 个地方 : 实现方法过滤的拦截器需要继承 MethodFilterInterceptor 抽象类,并且重写 doIntercept 方法定义对 Action 的拦截逻辑
在 MethodFilterInterceptor 抽象类中,额外增加 2 个方法:
● public void setExcludeMethods(String excludeMethods)
: 排除需要过滤的方法 -----> 设置方法 “黑名单” ,所有在 excludMethods 字符串中列出的方法都不会被拦截
● public void setIncludeMethods(String includeMethods) : 设置需要过滤的方法 -----> 设置方法 “白名单” ,所有在 includeMehods 字符串中列出的方法都会被拦截
注意 : 如果一个方法同时在 excludeMethods 和 includeMethods 中列出,则该方法会被拦截
因为 MethodFilterInterceptor 类包含如上 2 个方法,则该拦截器的子类也会获得这 2 个方法,可以在 struts.xml 中指定需要被拦截或者不需要被拦截的方法
LoginActionMy
package js.a; import com.opensymphony.xwork2.ActionSupport; public class LoginActionMy extends ActionSupport { private String username; private String password; public void setUsername(String username) { this.username = username; } public String getUsername() { return username; } public void setPassword(String password) { this.password = password; } public String getPassword() { return password; } public String execute() throws Exception { System.out.println("进入execute方法执行体.........."); Thread.sleep(1500); if (getUsername().equals("crazyit") && getPassword().equals("leegang")) { return SUCCESS; } else { return ERROR; } } }
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.2.dtd"> <struts> <constant name="struts.custom.i18n.resources" value="globalMessages"/> <constant name="struts.i18n.encoding" value="GBK"/> <package name="lee" extends="struts-default"> <interceptors> <interceptor name="myfilter" class="js.a.MyFilterInterceptor"> <param name="name">方法过滤拦截器</param> </interceptor> </interceptors> <action name="loginMy" class="js.a.LoginActionMy"> <result name="error">/10/erroMy.jsp</result> <result name="success">/10/welcomeMy.jsp</result> <!-- 拦截器一般配置在result元素之后! --> <interceptor-ref name="defaultStack"/> <interceptor-ref name="myfilter"> <param name="name">改名后的方法过滤拦截器</param> <!-- 不被拦截的方法 --> <param name="excludeMethods">execute,haha</param> <!-- 被拦截的方法 --> <param name="includeMethods">execute</param> </interceptor-ref> </action> <action name=""> <result>.</result> </action> </package> </struts>
同时指定多个方法,可以用 (,)隔开
excludeMethods 参数指定了 execute 和 haha 方法不需要被拦截,又通过 includeMethods 参数指定了 execute 方法需要拦截,两者冲突,以 includeMethods 参数指定的为准,即拦截器会拦截 execute 方法
Struts 2 中提供了这种方法过滤的拦截器有如下几个:
● TokenInterceptor
● TokenSessionStoreInterceptor
● DefaultWorkflowInterceptor
● ValidationInterceptor
loginMy.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <%@taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>登录页面</title> </head> <body> <form action="loginMy.action" method="post"> <table align="center"> <caption><h3>用户登录</h3></caption> <tr> <td>用户名:<input type="text" name="username"/></td> </tr> <tr> <td>密码:<input type="text" name="password"/></td> </tr> <tr align="center"> <td><input type="submit" value="登录"/> <input type="reset" value="重填" /></td> </tr> </table> </form> </body> </html>
welcomeMy.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>成功页面</title> </head> <body> 您已经登录! </body> </html>
erroMy.jsp
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>错误页面</title> </head> <body> 您不能登录! </body> </html>
<s:a href="" onclick="newWin('10/loginMy.jsp');" cssStyle="cursor: hand;">loginMy.jsp</s:a>
5.2 拦截器的执行顺序
以下代码基于 4.1
随着系统中配置拦截器的顺序的不同,系统中执行拦截器的顺序也不一样。通常认为: 先配置的拦截器,会先获得执行的机会,但实际的情况则有些出入
struts.xml
<?xml version="1.0" encoding="GBK"?> <!-- 指定Struts 2的配置文件的DTD信息 --> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <!-- 通过常量配置Struts 2的国际化资源信息 --> <constant name="struts.custom.i18n.resources" value="globalMessages"/> <!-- 通过常量配置Struts 2所使用的解码集--> <constant name="struts.i18n.encoding" value="GBK"/> <!-- 配置本系统所使用的包 --> <package name="lee" extends="struts-default"> <!-- 配置应用所使用的拦截器 --> <interceptors> <!-- 配置mysimple拦截器 --> <interceptor name="mysimple" class="lee.SimpleInterceptor"> <!-- 为拦截器指定参数值 --> <param name="name">简单拦截器</param> </interceptor> </interceptors> <!-- 配置处理用户请求的Action --> <action name="login" class="lee.LoginAction"> <!-- 配置结果映射 --> <result name="error">/error.jsp</result> <result name="success">/welcome.jsp</result> <!-- 拦截器一般配置在result元素之后! --> <interceptor-ref name="defaultStack"/> <!-- 下面的配置片段两次引用同一个拦截器 --> <interceptor-ref name="mysimple"> <param name="name">第一个</param> </interceptor-ref> <interceptor-ref name="mysimple"> <param name="name">第二个</param> </interceptor-ref> </action> <action name=""> <result>.</result> </action> </package> </struts>
从运行后台里显示内容可以得出结论: 在 Action 的控制逻辑方法执行之前,位于拦截器链前面的拦截器将先发生作用;在 Action 的控制方法执行之后,位于拦截器链前面的拦截器将后发生作用
5.3 拦截结果的监听器
以下代码基于 5.1
为了精确定义在 execute() 执行结束后,在处理物理资源转向之前的动作,需要使用拦截结果监听器,这个监听器是通过手动注册在拦截内部的 。
实现拦截结果监听器,必须实现 PreResultListener 接口:
MyPreResultListener.java
package js.a; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.PreResultListener; public class MyPreResultListener implements PreResultListener { // 定义在处理Result之前的行为 public void beforeResult(ActionInvocation invocation, String resultCode) { // 打印出执行结果 System.out.println("返回的逻辑视图为:" + resultCode); } }
resultCode
参数就是被拦截 Action
的 execute()
返回值。
虽然 beforeResult() 也获得 ActionInvocation 参数,但通过这个参数来控制 Action 已经没有用了,因为 execute() 已经执行结束
拦截器代码 BeforeResultInterceptor.java :
package js.a;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class BeforeResultInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception {
// 将一个拦截结果的监听器注册给该拦截器
invocation.addPreResultListener(new MyPreResultListener());
System.out.println("execute方法执行之前的拦截...");
// 调用下一个拦截器,或者Action的执行方法
String result = invocation.invoke();
System.out.println("execute方法执行之后的拦截...");
return result;
}
}
结果:
execute方法执行之前的拦截... 进入execute方法执行体.......... 返回的逻辑视图为::error execute方法执行之后的拦截...
上面代码手动注册了一个拦截结果的监听器,该监听器中的 beforeResult()
肯定会在系统处理物理资源转向之前被执行,上面的拦截器也定义了需要在处理物理资源转向之前执行的代码
定义在 MyPreResultListener
类中的 beforeResult()
比 BeforeResultInterceptor
类中的 intercept()
中在 Result
之前执行的动作,更早执行。
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.2.dtd"> <struts> <constant name="struts.custom.i18n.resources" value="messageResource"/> <constant name="struts.i18n.encoding" value="GBK"/> <package name="js.a" extends="struts-default" namespace="/10"> <!-- 应用所需使用的拦截器都在该元素下配置 --> <interceptors> <interceptor name="resultInterceptor" class="js.a.BeforeResultInterceptor"/> </interceptors> <action name="loginA" class="js.a.LoginActionMy"> <result name="error">/10/error.jsp</result> <result name="success">/10/welcome.jsp</result> <!-- 拦截器一般配置在result元素之后! --> <interceptor-ref name="defaultStack"/> <interceptor-ref name="resultInterceptor"/> </action> <action name=""> <result>.</result> </action> </package> </struts>
LoginActionMy.java 在 5.1 中
error.jsp,welcome.jsp 在 4.1 中
loginMy1.jsp
<body> <form action="loginA.action" method="post"> <table align="center"> <caption><h3>用户登录</h3></caption> <tr> <td>用户名:<input type="text" name="username"/></td> </tr> <tr> <td>密码:<input type="text" name="password"/></td> </tr> <tr align="center"> <td><input type="submit" value="登录"/> <input type="reset" value="重填" /></td> </tr> </table> </form> </body>
<s:a href="" onclick="newWin('10/loginMy1.jsp');" cssStyle="cursor: hand;">loginMy1.jsp</s:a>
5.4 覆盖拦截器栈里特定拦截器的参数
以下代码基于 5.1
拦截器栈中有多个拦截器,如果要覆盖该拦截器栈中某个拦截器的指定参数,需要在配置使用拦截器栈的地方 <interceptor-ref />
元素中使用 <param/>
元素来传入参数,在 <param />
中指定参数名时应使用:“拦截器名.参数名”
形式,这样才能让 Struts 2
明白我们想覆盖哪个拦截器的哪个参数
<?xml version="1.0" encoding="GBK"?> <!-- 指定Struts 2的配置文件的DTD信息 --> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <!-- 通过常量配置Struts 2的国际化资源信息 --> <constant name="struts.custom.i18n.resources" value="globalMessages"/> <!-- 通过常量配置Struts 2所使用的解码集--> <constant name="struts.i18n.encoding" value="GBK"/> <!-- 配置本系统所使用的包 --> <package name="lee" extends="struts-default"> <!-- 配置应用所使用的拦截器 --> <interceptors> <!-- 配置mysimple拦截器 --> <interceptor name="mysimple" class="lee.SimpleInterceptor"> <!-- 为拦截器指定参数值 --> <param name="name">简单拦截器</param> </interceptor> <!-- 配置第二个拦截器 --> <interceptor name="second" class="lee.SecondInterceptor"/> <!-- 配置名为my-stack的拦截器栈 --> <interceptor-stack name="my-stack"> <!-- 配置拦截器栈内的第一个拦截器 --> <interceptor-ref name="mysimple"> <param name="name">第一个</param> </interceptor-ref> <!-- 配置拦截器栈内的第二个拦截器 --> <interceptor-ref name="second"> <param name="name">第二个</param> </interceptor-ref> </interceptor-stack> </interceptors> <!-- 配置处理用户请求的Action --> <action name="login" class="lee.LoginAction"> <!-- 配置结果映射 --> <result name="error">/error.jsp</result> <result name="success">/welcome.jsp</result> <!-- 拦截器一般配置在result元素之后! --> <interceptor-ref name="defaultStack"/> <!-- 应用上面的拦截器栈 --> <interceptor-ref name="my-stack"> <!-- 覆盖指定拦截器的指定参数值 --> <param name="second.name">改名后的拦截器</param> </interceptor-ref> </action> <action name=""> <result>.</result> </action> </package> </struts>
上面配置了一个名为 my-stack
的拦截器栈,并且包括 2
个拦截器,这 2
个拦截器分别引用 mysimple
和 second
拦截器,并且覆盖了 mysimple
拦截器的默认参数
在 login
的 Action
中使用 my-stack
拦截器时,使用了 <param .../>
元素来覆盖了该拦截器栈里 second
拦截器的 name
参数 (second.name
)
发表评论
文章已被作者锁定,不允许评论。
-
Struts1 与 Struts2 的12点区别
2011-11-16 11:14 7401) 在Action实现类方面 ... -
Struts 2 的 Ajax 支持(四)
2011-03-14 16:21 17435.4 tabbedpanel 标签 ... -
Struts 2 的 Ajax 支持(三)
2011-02-11 13:18 24365.2 submit 和 a 标签 ... -
Struts 2 的 Ajax 支持(二)
2011-01-27 14:08 2398四、 基于 Dojo 的 pub-sub 事件模型 ... -
Struts 2 的 Ajax 支持(一)
2011-01-20 14:55 2486一、 Ajax 概述 ... -
Struts 2 的拦截器(三)
2011-01-20 13:09 2907六、 拦截器示例 : 实现权限控制 权限检 ... -
Struts 2 的拦截器(一)
2010-12-31 16:53 2021一、 理解拦截器 ... -
Struts 2 的标签库(五)
2010-12-29 11:35 11446.8 select 标签 以下代码 都是基 ... -
Struts 2 的标签库(四)
2010-12-24 16:21 1646六、 表单标签 表单标签,分为 2 种 : f ... -
Struts 2 的标签库(三)
2010-12-20 14:15 1972四、 数据标签 数据标签主要 ... -
Struts 2 的标签库(二)
2010-12-15 16:21 2031三、 控制标签 Str ... -
Struts 2 的标签库(一)
2010-12-13 13:47 1363一、 Struts 2 标签库概述 ... -
Struts 2 的国际化(二)
2010-12-09 13:25 2260二、 Struts 2 的国际化入门 ... -
Struts 2 的国际化(一)
2010-12-06 22:44 1306一、 程序国际化简 ... -
Struts2 上传和下载文件(三)
2010-12-03 14:58 1795三、 同时上传多个 ... -
Struts2 上传和下载文件(二)
2010-11-29 13:37 1984二、 Struts 2 的文件上传 ... -
Struts2 上传和下载文件(一)
2010-11-17 22:28 2088一、 文件上传的原理 1. 表单元 ... -
struts2 输入校验 (四)
2010-11-15 22:43 1217六、 手动完成输入校验 对于一些特殊的检验 ... -
struts2 输入校验 (三)
2010-11-08 13:25 1721五、 内建校验器 S ... -
struts2 输入校验 (二)
2010-10-28 11:01 2386二、 基本输入校验 MVC ...
相关推荐
Struts2拦截器(Interceptor) Struts2拦截器(Interceptor)
在Struts2中,拦截器(Interceptors)扮演着核心角色,增强了框架的功能和灵活性。这篇文章将深入探讨Struts2拦截器的概念、工作原理以及如何在实际应用中使用它们。 **一、什么是Struts2拦截器** 拦截器是基于AOP...
2. **拦截器链**:在Struts2中,多个拦截器可以形成一个拦截器链,每个拦截器按照定义的顺序依次执行。如果所有拦截器都允许Action执行,那么Action的结果将被传递到下一个拦截器,直到整个链执行完毕。 ### 二、...
在Struts2中,拦截器(Interceptor)扮演着核心角色,它们允许开发者在Action执行前后插入自定义的逻辑,如日志、权限检查、事务管理等。现在我们将深入探讨Struts2的拦截器机制及其实例应用。 ### 一、Struts2拦截...
### Struts2拦截器详解 #### 一、Struts2拦截器概述 Struts2框架作为Java Web开发中的一种流行框架,其核心组件之一便是**拦截器**。拦截器不仅在Struts2中扮演着重要角色,更是整个框架灵活性与扩展性的基石。...
Struts2拦截器.ppt Struts2拦截器.ppt Struts2拦截器.ppt
标题“struts2拦截器”指的是Struts2框架中的拦截器机制,这是一个关键的组件,可以让我们在不修改实际业务代码的情况下,实现对请求处理流程的扩展和定制。 描述中提到的“基于struts2的拦截器测试,实现了页面的...
在这个“Struts2拦截器实现权限控制demo”中,我们将深入探讨如何利用拦截器来实现细粒度的用户权限管理。 首先,我们需要了解Struts2中的拦截器工作原理。拦截器是基于Java的动态代理模式实现的,它们按照配置的...
拦截器是Struts2框架的核心特性之一,它们扮演着处理请求、增强功能和实现业务逻辑的角色。在Struts2中,拦截器就像过滤器一样工作,通过链式调用在动作执行前后进行预处理和后处理。 首先,我们来理解一下拦截器的...
#### 二、Struts2拦截器的工作原理 拦截器的工作原理是基于责任链模式。当用户发起一个请求时,这个请求会经过一系列拦截器的处理,这些拦截器构成了一个责任链。每个拦截器都有机会处理请求或继续传递请求到下一个...
当请求到达控制器时,Struts2会依次调用这个栈中的拦截器,每个拦截器都有机会处理请求,然后决定是否将请求传递给下一个拦截器或直接返回响应。 创建一个简单的Struts2拦截器,你需要遵循以下步骤: 1. 创建拦截...
拦截器是Struts2框架的核心组成部分,它们在请求处理流程中起到了关键的作用。在本文中,我们将深入探讨Struts2拦截器的工作原理。 ### 一、拦截器概念 拦截器是基于Java的动态代理机制实现的,它允许我们在Action...
在Struts2中,拦截器扮演着至关重要的角色,它们是实现MVC(Model-View-Controller)架构的关键组件之一。拦截器允许开发者在动作执行前后插入自定义逻辑,比如日志记录、权限检查、数据验证等,而无需修改核心业务...
拦截器是Struts2框架的核心组件之一,它允许开发者在动作执行前后插入自定义逻辑,实现如权限验证、日志记录、性能优化等多种功能。在"Struts2 拦截器注解"这个主题中,我们将深入探讨如何利用注解来简化拦截器的...
首先,理解拦截器的定义:拦截器是AOP(面向切面编程)的一个概念,在Struts2中,拦截器是基于Java的动态代理机制实现的。它们是一系列实现了`Interceptor`接口的类,可以在Action执行前后插入额外的行为。这些行为...
拦截器是Struts2框架的一个重要组成部分,能够帮助开发者实现一些在请求处理前后执行的通用逻辑,如日志记录、权限验证、数据校验等。在本场景中,我们将探讨如何使用Struts2拦截器来实现对不文明字迹或者敏感词汇的...
在Struts2中,拦截器(Interceptor)扮演着至关重要的角色,它允许开发者在动作执行前后插入自定义逻辑,如日志记录、权限验证等。在本案例中,我们将深入探讨如何使用Struts2拦截器实现登录权限验证,同时结合...
这篇博客“Struts2 拦截器的执行顺序(二十九)”可能探讨了Struts2拦截器链的工作原理和它们的执行顺序,这对于理解Struts2的内部机制至关重要。 首先,让我们深入理解Struts2的拦截器。拦截器是在Action调用前后...
在本学习案例中,重点在于Struts2的拦截器(Interceptor)功能,这是Struts2的核心特性之一,它允许开发者在Action执行前后进行自定义处理,实现了灵活的业务逻辑控制和增强的功能。 首先,我们来理解一下什么是...
Struts2是一个强大的MVC框架,它通过使用拦截器(Interceptor)来实现业务逻辑与表现层的解耦,提供了一种灵活的扩展机制。在Struts2中,拦截器是AOP(面向切面编程)的一种实现,它可以监控、修改或增强方法调用的...