Struts2開發基礎
struts2採用攔截器的機制來處理使用者的請求,使得業務邏輯控制器能夠與ServletAPI完全脫離開。
1. Hello World!
配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Struts Demo</display-name> <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> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
配置struts.xml
<?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="default" namespace="/" extends="struts-default"> <action name="HelloWorld" class="example.HelloWorld"> <result name = "success" >/WEB-INF/jsp/example/HelloWorld.jsp</result> </action> </package> </struts>
Hello.java
import com.opensymphony.xwork2.ActionSupport;
public class Hello extends ActionSupport {
public final static String MESSAGE = "Hello World!";
private String msg;
public String getMessage() {
return msg;
}
public void setMessage(String msg) {
this.msg = msg;
}
public String execute() throws Exception {
setMessage(MESSAGE);
return SUCCESS;
}
}
將struts2應用部署到Tomcat
- 編譯.java檔案
- 在Tomcat/webapps/appname資料夾下建立WEB-INF資料夾
- 將struts2必須的包放入到站點/WEB-INF/lib下,
- 將編譯好的相應class檔案按照包的結構放在/WEB-INF/classes/相應的包目錄下。
- 將struts.xml放入/WEB-INF/classes/資料夾下
- 啟動Tomcat,在瀏覽器中訪問localhost:protal/appname/HelloWorld或者localhost:protal/appname。(建議指定Action)
struts2原理
當Web容器收到請求(HttpServletRequest)時,它將請求傳遞給一個標準的過濾鏈。接下來呼叫FilterDispatcher核心控制器,然後它呼叫ActionMapper確定請求哪個Action。ActionMapper返回一個收集Action詳細資訊的ActionMaping物件。
接下來FilterDispatcher將控制權委派給ActionProxy,ActionProxy呼叫配置管理器(ConfigurationManager) 從配置檔案中讀取配置資訊(struts.xml),然後通過反射建立ActionInvocation物件。ActionInvocation在呼叫Action之前會依次的呼叫所用配置攔截器(Interceptor ).
一旦執行結果返回結果字串,ActionInvocation負責查詢結果字串對應的(Result)然後執行這個Result。Result會呼叫一些模版(JSP)來呈現頁面,之後攔截器(Interceptor)會被反向執行,處理響應(response)。
簡單地說,Strusts2起到一個過濾器控制器的作用,這點從web.xml中可以看出來。
2. Struts2 配置設定
配置Action是struts2配置的核心內容。
(1) 包和名稱空間
struts2使用包來組織Action,在xml配置檔案中使用<package>標籤來組織一個包,Action使用<action>子元素來完成。
<package name="default" namespace="/" extends="struts-default">
<package>標籤必須指定name屬性,它是訪問的唯一標識,extends屬性指定繼承的父包,子包可以在父包中整合Action,攔截器,攔截器棧等配置。還有可選的abstract屬性,abstract="true"表示該包不能進行Action配置。
struts2的名稱空間機制用來避免命名衝突,同一名稱空間下不允許Action等重名,不同名稱空間下允許重名。<package>標籤的namespace屬性用於指定名稱空間,不允許對單獨的Action指定空間。
如果<package>沒有指定namespace屬性則屬於預設名稱空間。設定<package namespace = "/">指定為根名稱空間。如果請求為/space/*.actionweb容器會先在space名稱空間中尋找Action,如果未找到則在預設名稱空間中尋找Action,若仍未找到則會出現錯誤。如果請求為/*.action則在根名稱空間中尋找Action,這也說明了根名稱空間和預設名稱空間的區別。
(2) 配置Action
<action name="HelloWorld" class="example.HelloWorld">
<result name = "success" >
/WEB-INF/jsp/example/HelloWorld.jsp
</result>
</action>
Action必須指定URL,struts2的Action所處理URL即為namspace/actioname.action,或省略.action字尾。
Action作為邏輯控制器並不直接生成響應,而是返回一個代表處理結果的字串,<result>子標籤將返回的結果與物理檢視對應。
(3) 配置常量
struts2框架採用下列順序載入struts2常量:
1. struts-default.xml struts2-core.jar
2.struts2-plugin.xml
3.struts.xml
4.struts.properties
5.web.xml
後面載入的常量會覆蓋前面的常量。
為了模組化的配置,struts.xml可以使用include標籤包含其它xml配置檔案:
<include file="example.xml"/>
(4) 配置結果
1. result配置
struts2在struts.xml中使用<result>元素配置處理結果。處理結果依照作用域可以分為全域性結果和區域性結果,預設作為區域性結果。
<action name="HelloWorld" class="example.HelloWorld">
<result name = "success" >
/WEB-INF/jsp/example/HelloWorld.jsp
</result>
</action>
<result>元素要配置的屬性包括:
(1)name:對應Action返回的結果字串,若預設則預設為"SUCCESS"
(2)type: 指定result的型別
(3)location: 指定實際檢視資源,若預設則使用<result></>之間的字串作為檢視資源。
(4)parse: 是否允許在<result>中使用OGNL表示式,預設為"true"。
2. result型別
<result-type>可以在xml中自定義,struts-default.xml中定義了常用的result-type。
(1)dispatcher:
dispatcher是用於指定jsp檢視的結果型別,若預設type則預設為此型別。
(2)plainText:
plainText用於以純文字方式返回檢視的原始碼。plainText結果型別可指定如下引數:
loacation:指定實際檢視資源
charSet: 指定字符集
(3)redirect
dispatcher使用請求轉發的方式返回檢視資源,redirect使用重定向的方式返回檢視資源。redirect型別會呼叫HttpServlet.sendRedirect方法來重定向,此方法將會重新建立一個request,原請求中的資料將會全部丟失。
redirect方式允許配置loaction和parse兩個屬性。
(4)redirectAction
redirectAction型別與redirect類似,同樣是生成一個新的請求。區別在於,redirectAction使用ActionMapperFactory的ActionMapper來將請求重定向到另一個Action。
redirect需要指定namespace和actionName來指定目標Action的namespace和Actionname。
3. 全域性結果
<result>用來配置區域性結果,只對它所屬的action有效。<globla-result>標籤用於配置全域性結果,對於所有Ation都有效。
<global-results> <result name="error">/WEB-INF/jsp/error.jsp</result> </global-results>
在匹配結果時優先匹配區域性結果,當區域性結果不匹配時才會匹配全域性結果。
3. 開發Action
(1) 實現Action
struts2 不要求Action類實現任何介面或繼承任何類,但為了標準化程式設計,struts2提供了Action介面定義了規範化的Action類,併為其提供了一個ActionSupport實現類( com.opensymphony.xwork2.ActionSupport;),通常我們繼承ActionSupport類並重寫public String execute(void)方法。ActionSupport定義了資料校驗,獲取國際化資訊的方法,在struts.xml的Action配置中若省略class屬性則會使用ActionSupport作為實現類。
execute方法返回一個代表處理結果的字串,並根據xml中的配置將其對映為物理檢視。strust2定義了5個標準字串:"SUCCESS","ERROR","LOGIN","INPUT","NONE";實際上仍可使用自定義的字串作為處理結果。
(2) 訪問Servlet API
1. 使用ActionContext
struts2的Action不再與Servlet API耦合,但提供了訪問Servlet API的方法。struts2提供了ActionContect類,並通過該類訪問Servlet API。
(1) ActionContext ctx = ActionContext.getContext();
getContext()方法可以獲得ActionContext例項。
(2) Map session = ctx.getSession();
獲得session例項。
(3) Map sctx = ctx.getApplication();
獲得ServletContext例項
(4) void setSession(Map session);
設定session。
(5) void setApplication(Map application)
設定Application。
(6) Map getParameters()
等價於HttpServletRequest.getParameterMap()方法,得到請求的引數。
(7) Object get(Object key)
等價於HttpServletRequest.getAttribute(String key)方法。
2. 使用ServletActionContext
ServletActionContext提供靜態方法獲取相應物件。
(1)獲得PageContext物件。
static PageContext getPageContext()
(2)獲得HttpServletRequest物件。
static HttpServletRequest getRequest()
(3)獲得HttpServletReponse物件。
static HttpServletReponse getReponse()
(4)獲得ServletContext物件。
static ServletContext getServletContext()
3. 實現Aware系列介面
(1)ServletResponseAware
實現該介面該介面的類可以直接訪問HttpServletResponse物件,但必須實現setServletResponse()介面。
class MyAction
implements Action, ServletResponseAware
{
private HttpServletResponse response;
public void setServletResponse (HttpServletResponse response) {
this.response = response;
}
}
(2)ServletRequestAware
與ServletResponseAware類似,實現該介面的類可以訪問HttpServletRequest物件,只要實現方法:
public void setServletRequest(HttpServletRequest request)
(3) ServletContextAware
與ServletResponseAware類似,實現該介面的類可以訪問HttpServletContext物件,只要實現方法:
public void setServletContext(HttpServletContext request)