攔截器(Interceptor)是Struts 2的核心組件,Struts 2框架的大部分功能都是經過攔截器來完成的,例如數據校驗,國際化,文件上傳和下載等。爲了實現這些功能,Struts 2框架提供了一個強大的攔截器策略。html
攔截器的配置是在struts.xml文件中完成的,攔截器一般使用<interceptor>標籤來定義,該標籤有兩個屬性name和class,分別用來指定攔截器名稱及其實現類。java
<interceptor name="interceptorName" class="interceptorClass"> <param name="paramName">paramValue</param> </interceptor>
<package name="default" extends="struts-default" > <interceptors> <!--定義兩個攔截器,攔截器名分別爲interceptor1和interceptor2--> <interceptor name="interceptor1" class=」interceptorClass」/> <interceptor name="interceptor2" class=」interceptorClass」/> <!--定義一個攔截器棧,攔截器包含了兩個攔截器--> <interceptor-stack name="myStack"> <interceptor-ref name="interceptor1"/> <interceptor-ref name="interceptor2"/> </interceptor-stack> </interceptors> </package>
注意:在一個攔截器棧中也能夠引用另外一個攔截器棧。spring
<?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> <package name="default" extends="struts-default"> <interceptors> <!--定義兩個攔截器--> <interceptor name="interceptor1" class="interceptorClass"/> <interceptor name="interceptor2" class="interceptorClass"/> <!--定義一個攔截器棧--> <interceptor-stack name="myStack"> <interceptor-ref name="interceptor1"/> <interceptor-ref name="interceptor2"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <!--配置包下的默認攔截器,既能夠是攔截器,也能夠是攔截器棧--> <default-interceptor-ref name="myStack"/> <action name="login" class="tutorial.Login"> <result name="input">login.jsp</result> </action> </package> </struts>
struts-default.xml文件位於:struts2-core-2.3.x.jar文件中。包struts-default內容參考以下(摘錄自struts-default.xml):apache
<package name="struts-default" abstract="true"> <result-types> <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/> <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/> <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/> <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/> <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/> <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/> <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/> <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/> <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" /> </result-types> <interceptors> <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/> <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/> <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/> <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/> <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/> <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" /> <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" /> <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" /> <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/> <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/> <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/> <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/> <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/> <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/> <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/> <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/> <interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/> <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/> <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/> <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/> <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/> <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/> <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/> <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/> <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/> <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/> <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" /> <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" /> <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" /> <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" /> <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" /> <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" /> <!-- Basic stack --> <interceptor-stack name="basicStack"> <interceptor-ref name="exception"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> </interceptor-stack> <!-- Sample validation and workflow stack --> <interceptor-stack name="validationWorkflowStack"> <interceptor-ref name="basicStack"/> <interceptor-ref name="validation"/> <interceptor-ref name="workflow"/> </interceptor-stack> <!-- Sample file upload stack --> <interceptor-stack name="fileUploadStack"> <interceptor-ref name="fileUpload"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- Sample model-driven stack --> <interceptor-stack name="modelDrivenStack"> <interceptor-ref name="modelDriven"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- Sample action chaining stack --> <interceptor-stack name="chainStack"> <interceptor-ref name="chain"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- Sample i18n stack --> <interceptor-stack name="i18nStack"> <interceptor-ref name="i18n"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- An example of the paramsPrepareParams trick. This stack is exactly the same as the defaultStack, except that it includes one extra interceptor before the prepare interceptor: the params interceptor. This is useful for when you wish to apply parameters directly to an object that you wish to load externally (such as a DAO or database or service layer), but can't load that object until at least the ID parameter has been loaded. By loading the parameters twice, you can retrieve the object in the prepare() method, allowing the second params interceptor to apply the values on the object. --> <interceptor-stack name="paramsPrepareParamsStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="i18n"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param> </interceptor-ref> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> </interceptor-stack> <!-- A complete stack with all the common interceptors in place. Generally, this stack should be the one you use, though it may do more than you need. Also, the ordering can be switched around (ex: if you wish to have your servlet-related objects applied before prepare() is called, you'd need to move servletConfig interceptor up. This stack also excludes from the normal validation and workflow the method names input, back, and cancel. These typically are associated with requests that should not be validated. --> <interceptor-stack name="defaultStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="i18n"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="scopedModelDriven"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="debugging"/> </interceptor-stack> <!-- The completeStack is here for backwards compatibility for applications that still refer to the defaultStack by the old name --> <interceptor-stack name="completeStack"> <interceptor-ref name="defaultStack"/> </interceptor-stack> <!-- Sample execute and wait stack. Note: execAndWait should always be the *last* interceptor. --> <interceptor-stack name="executeAndWaitStack"> <interceptor-ref name="execAndWait"> <param name="excludeMethods">input,back,cancel</param> </interceptor-ref> <interceptor-ref name="defaultStack"/> <interceptor-ref name="execAndWait"> <param name="excludeMethods">input,back,cancel</param> </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="defaultStack"/> <default-class-ref class="com.opensymphony.xwork2.ActionSupport" /> </package>
<package name="default" extends="struts-default"> <interceptors> <!--定義三個攔截器--> <interceptor name="interceptor1" class="interceptorClass"/> <interceptor name="interceptor2" class="interceptorClass"/> <interceptor name="interceptor3" class="interceptorClass"> <param name="paramName">paranValue1</param> </interceptor> <!--定義一個攔截器棧--> <interceptor-stack name="myStack"> <interceptor-ref name="interceptor1"/> <interceptor-ref name="interceptor2"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <action name="login" class="tutorial.Login"> <result name="input">login.jsp</result> <!--在名爲login的Action中使用已經定義的攔截器--> <interceptor-ref name="interceptor1"/> <interceptor-ref name="interceptor2"/> <interceptor-ref name="interceptor3"> <param name="paramName">paramValue2</param> </interceptor-ref> <interceptor-ref name="myStack"/> </action> </package>
注意:攔截器的參數指定有兩種方式,一種是在定義攔截器時指定參數,該種方式指定的參數是默認參數;另外一種是在使用攔截器時指定參數,該種方式指定的參數將會覆蓋默認參數值。編程
上述內容摘錄自:《Java Web整合開發實戰》第8章cookie
login.jsp,登陸界面session
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ page isELIgnored="false"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> <font style="color:red"><s:property value="errorMessage"/></font> <s:form action="intercepLogin" method="post"> 帳號:<s:textfield name="username"></s:textfield> <br /> 密碼:<s:textfield name="password"></s:textfield> <br /> <s:submit value="提交"></s:submit> </s:form> </body> </html>
showDetail.jsp,顯示詳細信息頁面app
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ page isELIgnored="false"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <body> Hello, we are here! </body> </html>
InptercepLoginAction.java,處理登陸請求框架
package com.clzhang.struts2.demo11; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class InptercepLoginAction extends ActionSupport { private String username; private String password; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String execute() { System.out.println(username + "\t" + password); // 一到登陸頁面,即移除session中變量 ActionContext.getContext().getSession().remove("userInfo"); // 只要用戶名與密碼長度大於等於4,都認爲是合法用戶 if (username.trim().length() >= 4 && password.trim().length() >= 4) { ActionContext.getContext().getSession().put("userInfo", username); return SUCCESS; } return INPUT; } }
ShowAction.java,處理顯示詳細信息請求jsp
package com.clzhang.struts2.demo11; import com.opensymphony.xwork2.ActionSupport; public class ShowAction extends ActionSupport { public String execute() { return SUCCESS; } }
LoginInterceptor.java,攔截器類,處理檢查用戶是否已經登陸
package com.clzhang.struts2.demo11; import java.util.Map; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class LoginInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { // 取得請求相關的ActionContext實例 ActionContext ctx = invocation.getInvocationContext(); Map session = ctx.getSession(); String user = (String)session.get("userInfo"); // 若是沒有登錄 if (user != null) { System.out.println("當前用戶已經登陸,繼續處理請求..."); return invocation.invoke(); } ctx.put("errorMessage", "你尚未登陸,或者登陸超時,請從新登陸後繼續操做!"); return Action.LOGIN; } }
<?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="myStruts" extends="struts-default"> <interceptors> <interceptor name="authority" class="com.clzhang.struts2.demo11.LoginInterceptor"> </interceptor> <!-- 攔截器棧 --> <interceptor-stack name="myDefault"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="authority"/> </interceptor-stack> </interceptors> <global-results> <result name="login">/struts2/demo11/login.jsp</result> </global-results> <action name="intercepLogin" class="com.clzhang.struts2.demo11.InptercepLoginAction"> <result name="input">/struts2/demo11/login.jsp</result> <result name="success" type="redirectAction"> <param name="actionName">intercepShow</param> </result> </action> <action name="intercepShow" class="com.clzhang.struts2.demo11.ShowAction"> <result>/struts2/demo11/showDetail.jsp</result> <interceptor-ref name="myDefault"/> </action> </package> </struts>
打開IE,輸入地址:http://127.0.0.1:8080/st/struts2/intercepShow.action
結果以下:
任意輸入4位長度用戶名與密碼,登陸,便可以顯示詳細頁面。