(轉)Struts2訪問Servlet的API及......


http://blog.csdn.net/yerenyuan_pku/article/details/67315598

Struts2訪問Servlet的API

前面已經對Struts2的流程已經執行完成了,但是如果表單中有參數,那如何進行接收又或者我們需要向頁面保存一些數據,又要如何完成呢?我們可以通過學習Struts2訪問Servlet的API來實現這樣的功能。 
在Struts2中,Action並沒有直接和Servlet API進行耦合,也就是說在Struts2的Action中不能直接訪問Servlet API。雖然Struts2中的Action訪問Servlet API麻煩一些,但是這卻是Struts2中Action的重要改良之一,方便Action進行單元測試。 
盡管Action和Servlet API解耦會帶來很多好處,然而在Action中完全不訪問Servlet API幾乎是不可能的,在實現業務邏輯時,經常要訪問Servlet中的對象,如session、request和application等。在Struts2中,訪問Servlet API有3種方法,具體如下:

通過ActionContext類訪問

Struts2框架提供了ActionContext類來訪問Servlet API,ActionContext是Action執行的上下文對象,在ActionContext中保存了Action執行所需要的所有對象,包括parameters,request,session,application等。下面列舉ActionContext類訪問Servlet API的幾個常用方法,具體如表所示: 

這里寫圖片描述
列舉的是ActionContext類訪問Servlet API的常用方法,要訪問Servlet API,可以通過如下方式進行,具體示例代碼如下:

ActionContext context = ActionContext.getContext(); context.put("name", "liayun"); context.getApplication().put("name", "liayun"); context.getSession().put("name", "liayun");

 

在上述示例代碼中,通過ActionContext類中的方法調用,分別在request、application和session中放入了(“name”, “liayun”)對。可以看到,通過ActionContext類可以非常簡單地訪問JSP內置對象的屬性。 
為了讓大家更好地掌握如何通過ActionContext類來訪問Servlet API,接下來通過一個具體的案例來演示ActionContext的使用。

  1. 在Eclipse中創建一個名稱為struts2_day02的Web項目,將Struts2所需的Jar包復制到項目的lin目錄中,並發布到類路徑下。在WebContent目錄下編寫一個簡單的登錄頁面form.jsp,如下所示:

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/userForm.action" method="post"> username:<input type="text" name="username" /><br/> password:<input type="password" name="password" /><br/> <input type="submit" value="提交" /> </form> </body> </html>
    • 1

    在該頁面中,編寫了用戶名和密碼輸入框和一個登錄提交按鈕。

  2. 在WEB-INF目錄下創建一個名稱為web.xml的文件,在該文件中配置Struts2的核心控制器,如下所示:

    <!-- 配置Struts2的過濾器 --> <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>
    • 1
  3. 在src目錄下創建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="demo" extends="struts-default" namespace="/"> <!-- action獲取表單提交數據 --> <action name="userForm" class="cn.itcast.action.form.UserFormAction"></action> </package> </struts>
    • 1
  4. 在src目錄下創建一個cn.itcast.action.form包,再在cn.itcast.action.form包中創建UserFormAction類,進行業務邏輯處理,如下所示:

    public class UserFormAction extends ActionSupport { @Override public String execute() throws Exception { // 獲取表單提交的數據 ActionContext類 // 1.先得到ActionContext對象 ActionContext context = ActionContext.getContext(); // 2.再調用方法得到表單提交的數據 Map<String, Object> map = context.getParameters(); // 遍歷 Set<String> keys = map.keySet(); for (String key : keys) { // 根據key得到value // 在map里面的value的類型是數組形式 String[] value = (String[]) map.get(key); System.out.println(key + "::" + Arrays.toString(value)); // 數組作為字符串輸出 } return NONE; } }
    • 1

通過特定接口訪問

Struts2框架提供了ActionContext類來訪問Servlet API,雖然這種方法可以訪問Servlet API,但是無法直接獲得Servlet API實例。為了在Action中直接訪問Servlet API,Struts2還提供了一系列接口,具體如下:

  • ServletRequestAware:實現該接口的Action可以直接訪問Web應用的HttpServletRequest實例。
  • ServletResponseAware:實現該接口的Action可以直接訪問Web應用的HttpServletResponse實例。
  • SessionAware:實現該接口的Action可以直接訪問Web應用的HttpSession實例。
  • ServletContextAware:實現該接口的Action可以直接訪問Web應用的ServletContext實例。

下面以ServletRequestAware為例,講解如何在Action中訪問HttpServletRequest實例。

  1. 將UserFormAction類的代碼修改為:

    public class UserFormAction extends ActionSupport implements ServletRequestAware { HttpServletRequest request; public void setServletRequest(HttpServletRequest request) { this.request = request; } @Override public String execute() throws Exception { // 定義成員變量,把setServletRequest方法里面的request對象賦值到成員變量的request里面 String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println(username + "::" + password); return NONE; } }
    • 1

    在上述文件中,自定義的UserFormAction類實現了Action的ServletRequestAware接口。需要注意的是,UserFormAction類中必須實現setServletRequest()方法和execute()方法,通過setServletRequest()方法,可以得到HttpServletRequest的實例,這是在調用execute()方法或者其他自定義的方法之前就調用的,然后在execute()方法中,就可以訪問HttpServletRequest的屬性內容了。

  2. 重新發布struts2_day02項目,在瀏覽器地址欄中輸入http://localhost:8080/struts2_day02/form.jsp,成功訪問后可以看出,使用ServletRequestAware接口順利訪問了Servlet API。

通過ServletActionContext類訪問

為了直接訪問Servlet API,Struts2框架還提供了ServletActionContext類,該類包含了幾個常用的靜態方法,具體如下:

  • static HttpServletRequest getRequest():獲取Web應用的HttpServletRequest對象
  • static HttpServletResponse getResponse():獲取Web應用的HttpServletResponse對象
  • static ServletContext getServletContext():獲取Web應用的ServletContext對象
  • static PageContext getPageContext():獲取Web應用的PageContext對象

接下來,講解如何通過ServletActionContext訪問Servlet API。

  1. 將UserFormAction類的代碼修改為:

    public class UserFormAction extends ActionSupport { @Override public String execute() throws Exception { // 獲取表單提交的數據,使用ServletActionContext類 // 1.直接使用ServletActionContext類得到request對象 HttpServletRequest request = ServletActionContext.getRequest(); // 2.可直接調用request的方法得到表單提交的數據 String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println(username + "::" + password); // 在Action類中如何操作域對象 // 1.操作request域 HttpServletRequest request = ServletActionContext.getRequest(); request.setAttribute("request", "requsetValue"); // 2.操作session域 request.getSession().setAttribute("session", "sessionValue"); // 3.操作servletContext域 ServletContext servletContext = ServletActionContext.getServletContext(); servletContext.setAttribute("servletContext", "servletContextValue"); return NONE; } }
  2. 可發現使用表單post方式提交,在Struts2框架的Action中獲取數據時不會有亂碼問題,這時因為Struts2框架有一個常量設置,如下:

    struts.i18n.encoding=UTF-8
  3. 至於若采用表單的get方式提交,你也只能手動解決了。

  4. 重新運行struts2_day02項目,在瀏覽器的地址欄中輸入http://localhost:8080/struts2_day02/form.jsp

從以上內容可以看出,借助於ServletActionContext類的幫助,開發者也可以在Action中直接訪問Servlet API,避免了Action類實現ServletRequestAware、ServletResponseAware、SessionAware和ServletContextAware等XxxAware接口。雖然如此,該Action依然與Servlet API直接耦合,一樣不利於程序解耦。綜上三種訪問Servlet API的方式,建議在開發中優先使用ActionContext,以避免和Servlet API耦合。 
Servlet的API已經可以訪問了,那么在頁面跳轉的時候我們會發現其實Struts2默認使用的都是轉發,那如果我們要使用重定向,應該怎么辦呢?接下來我們來看下結果頁面的配置。

結果頁面的配置

在struts.xml文件中,result的配置非常簡單,使用<result>元素來配置result邏輯視圖與物理視圖之間的映射,<result>元素可以有name和type屬性,但這兩種屬性都不是必選的。

  • name屬性:指定邏輯視圖的名稱,默認值為success。
  • type屬性:指定返回的視圖資源的類型,不同的類型代表不同的結果輸出,默認值是dispatcher。

struts.xml文件中的<result>元素配置代碼如下所示:

<action name="person" class="cn.itcast.action.result.PersonAction"> <result name="success" type="dispatcher">/a.jsp</result> </action>

 

 

在上述配置中,使用了<result>元素的name、type屬性。其中,為Action配置了name為success的result映射,該映射的值可以是JSP頁面,也可以是一個Action的name值。用type屬性指定了該result的結果類型為dispatcher,它也是默認的結果類型。 
在結果頁面的配置中,Struts2有兩種配置的方式,一種稱之為全局結果頁面,一種稱之為局部結果頁面。全局結果是指在這個包下的所有返回相同字符串的值,都可以向這個頁面來進行跳轉。局部結果是指在某個Action中返回的字符串的值,會向這個頁面跳轉。

全局結果頁面

全局結果頁面是指在同一個包下面配置的Action中返回相同的字符串的值,都可以跳轉到該頁面。需要通過<global-results>進行配置。 
在src目錄下創建一個cn.itcast.action.result包,再在cn.itcast.action.result包中創建兩個Action類——PersonAction類和OrdersAction類,執行默認的execute()方法,默認方法都返回success,如下所示:

  • PersonAction.java

    public class PersonAction extends ActionSupport { @Override public String execute() throws Exception { return "success"; } }
  • OrdersAction.java

    public class OrdersAction extends ActionSupport { @Override public String execute() throws Exception { return "success"; } }

然后再在struts.xml文件對以上兩個Action類進行配置,如下:

<action name="person" class="cn.itcast.action.result.PersonAction"> <result name="success">/form.jsp</result> </action> <action name="orders" class="cn.itcast.action.result.OrdersAction"> <result name="success">/form.jsp</result> </action>

 

上面配置好了兩個action,兩個action都是執行execute()方法,兩個action的execute()方法都返回success,返回之后都到form.jsp這個頁面中,這樣寫功能沒有問題,但造成有很多重復的配置。所以可使用全局結果頁面進行配置,在action標簽所在的package標簽里面使用global-results進行配置。如下:

<!-- 配置全局結果頁面 --> <global-results> <result name="success">/form.jsp</result> </global-results> <action name="person" class="cn.itcast.action.result.PersonAction"> <!-- <result name="success">/form.jsp</result> --> </action> <action name="orders" class="cn.itcast.action.result.OrdersAction"> <!-- <result name="success">/form.jsp</result> --> </action>
  • 1

局部結果頁面

局部結果頁面是指在某個Action中根據該字符串的值進行頁面的跳轉。只對這個Action有效。

<action name="person" class="cn.itcast.action.result.PersonAction"> <result name="success" type="dispatcher">/a.jsp</result> </action>

 

在Struts2中,當框架調用Action對請求進行處理后,就要向用戶呈現一個結果視圖。現在我來舉例說明,在WebContent目錄下新建一個JSP頁面——a.jsp,它主要作為測試用,所以內容很簡單:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>aaaaaaaaaaaaaaaaaaaaaaaa</h1> </body> </html>

 

然后修改struts.xml文件的內容為:

<!-- 配置全局結果頁面 --> <global-results> <result name="success">/form.jsp</result> </global-results> <action name="person" class="cn.itcast.action.result.PersonAction"> <result name="success">/a.jsp</result> </action> <action name="orders" class="cn.itcast.action.result.OrdersAction"> <!-- <result name="success">/form.jsp</result> --> </action>

 

可得出結論:如果配置了全局結果頁面,也配置了局部結果頁面,那么最終以局部結果頁面為准

result標簽的type屬性

result標簽里面有一個type屬性,type屬性的作用——因為result標簽是配置到不同的路徑上去,所以type屬性表示配置如何到路徑上去(例如重定向或者轉發等)。 
在Struts2中,預定義了多種ResultType,其實就是定義了多種展示結果的技術。一個結果類型就是實現了com.opensymphony.xwork2.Result接口的類,Struts2把內置的<result-type>都放在struts-default包中,struts-default包就是配置包的父包,這個包定義在struts2-core-2.3.24.jar包中的根目錄下的struts-default.xml文件中,可以找到相關的<result-type>的定義。 
每個<result-type>元素都是一種視圖技術或者跳轉方式的封裝,其中的name屬性指出在<result>元素中如何引用這種視圖技術或者跳轉方式,對應着<result>元素的type屬性。Struts2中預定義的ResultType如表所示: 

注意:上面的兩個值dispatcher、redirect這兩個值表示配置到不同的頁面中。其中紅色的幾個值比較常用,需要重點記憶。其他的了解即可。 
接下來我就來演示type屬性的這兩個值——dispatcher、redirect。先舉例演示type屬性的值——dispatcher,表示的是轉發操作,type屬性默認就是這個值。 
將PersonAction類的代碼修改為:

public class PersonAction extends ActionSupport { @Override public String execute() throws Exception { // 向request域中放入一個值 HttpServletRequest request = ServletActionContext.getRequest(); request.setAttribute("req", "requestValue"); return "success"; } }

 

然后修改struts.xml文件的內容為:

<global-results> <result name="success">/form.jsp</result> </global-results> <action name="person" class="cn.itcast.action.result.PersonAction"> <result name="success" type="dispatcher">/a.jsp</result> </action> <action name="orders" class="cn.itcast.action.result.OrdersAction"> <!-- <result name="success">/form.jsp</result> --> </action>

 

緊接着將a.jsp頁面的內容修改為:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>request域中的值:${requestScope.req }</h1> </body> </html>

 

這時在瀏覽器的地址欄中輸入http://localhost:8080/struts2_day02/person.action,回車,則會顯示如下效果: 

再來舉例演示type屬性的值——redirect,表示的重定向操作。 
PersonAction類的代碼並不需要修改,我們只須修改struts.xml文件的內容為:

<global-results> <result name="success">/form.jsp</result> </global-results> <action name="person" class="cn.itcast.action.result.PersonAction"> <result name="success" type="redirect">/a.jsp</result> </action> <action name="orders" class="cn.itcast.action.result.OrdersAction"> <!-- <result name="success">/form.jsp</result> --> </action>

 

這時在瀏覽器的地址欄中輸入http://localhost:8080/struts2_day02/person.action,回車,則會顯示如下效果: 

到這我們已經了解了Struts2的結果頁面的配置了,也知道如何接收數據了,但是接收過來的數據,往往需要進行封裝才會向業務層進行傳遞,那么作為一個框架,如果連這點功能都沒有,那就太不像是一個“框架”了,那么在Struts2中提供了對於數據封裝的幾種方式。接下來我們就來學習一下。

Struts2的數據封裝

在很多的實際開發中的場景中,頁面提交請求參數到Action,在Action中接收參數並且對請求參數需要進行數據的封裝。封裝到一個JavaBean中,然后將JavaBean傳遞給業務層。那么這些操作Struts2已經替我們都想好了。Struts2將數據的封裝分成兩大類,一類被稱為是屬性驅動,一類被稱為是模型驅動。在講這兩種方式之前,我們來使用傳統方式封裝數據到JavaBean對象中。

使用傳統方式封裝數據到JavaBean對象

首先在WebContent目錄下新建一個JSP頁面——formdata.jsp,內容如下:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/data1.action" method="post"> username:<input type="text" name="username" /><br/> password:<input type="password" name="password" /><br/> <input type="submit" value="提交" /> </form> </body> </html>

 

然后新建一個cn.itcast.action.data包,在該包中創建一個封裝數據的JavaBean——User.java。

public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User [username=" + username + ", password=" + password + "]"; } }

 

接着再在該包下創建一個Action類——Data1Action.java:

public class Data1Action extends ActionSupport { @Override public String execute() throws Exception { // 1.獲取表單提交的數據 HttpServletRequest request = ServletActionContext.getRequest(); String username = request.getParameter("username"); String password = request.getParameter("password"); // 2.把表單提交的數據封裝到實體類里面去 User user = new User(); user.setUsername(username); user.setPassword(password); System.out.println(user); return NONE; } }

 

最后在struts.xml核心配置文件中配置好該Action,如下:

<action name="data1" class="cn.itcast.action.data.Data1Action"></action>

 

了解了如何使用傳統方式封裝數據到JavaBean對象之后,我們來看第一種:屬性驅動。

屬性驅動

屬性驅動可以細分為兩種,一種只需要提供屬性的set方法即可。另一種可以通過表達式方式直接封裝到對象中。 
在Struts2中,可以直接在Action中定義各種Java基本數據類型的字段,使這些字段與表單數據相對應,並利用這些字段進行數據傳遞。

屬性驅動方式一:提供屬性的set方法的方式

首先修改formdata.jsp頁面的內容為:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/data2.action" method="post"> username:<input type="text" name="username" /><br/> password:<input type="password" name="password" /><br/> <input type="submit" value="提交" /> </form> </body> </html>

 

然后再在cn.itcast.action.data包中創建一個Action類——Data2Action.java:

public class Data2Action extends ActionSupport { // 1.定義成員變量 private String username; private String password; // 2.生成set和get方法 public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String execute() throws Exception { System.out.println(username + "..." + password); return NONE; } }

 

注意:在Action類里面定義成員變量時,成員變量的名稱要和表單輸入項的name屬性值一樣。 
最后在struts.xml核心配置文件中配置好該Action,如下:

<action name="data2" class="cn.itcast.action.data.Data2Action"></action>

 

以上這種方式需要通過在Action中定義屬性,並且提供屬性的set方法來完成。這種方式只需要提供set方法即可。但若需要傳入的數據很多的話,那么Action的屬性也會變得很多。再加上屬性有對應的getter/setter方法,Action類的代碼會很龐大,在Action里編寫業務的代碼時,會使Action非常臃腫,不夠簡潔。那么要怎樣解決這個問題呢? 
把屬性和相應的getter/setter方法從Action里提取出來,單獨作為一個值對象,這個對象就是用來封裝這些數據的,在相應的Action里直接使用這個對象,而且可以在對個Action里使用。采用這種方式,一般以JavaBean來實現,所封裝的屬性和表單的屬性一一對應,JavaBean將成為數據傳遞的載體。

屬性驅動方式二:頁面提供表達式方式

首先修改formdata.jsp頁面的內容為:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/fieldDemo.action" method="post"> username:<input type="text" name="user.username" /> password:<input type="password" name="user.password" /><br/> <input type="submit" value="提交" /> </form> </body> </html>

 

然后再在cn.itcast.action.data包中創建一個Action類——FieldDemoAction.java:

public class FieldDemoAction extends ActionSupport { // 1.聲明實體類的變量 private User user; // 生成user變量的set和get方法 public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String execute() throws Exception { System.out.println(user); return NONE; } }

 

以上這種方式需要提供對user變量的get方法,如果沒有提供get方法,在Struts2的底層就沒有辦法獲得到該對象,那么在user中只會有一個屬性被封裝進去,而其他的屬性都是null。 
值得幸運的是該方式在實際開發中使用的並不是很多!!!

模型驅動

在Struts2中,Action處理請求參數還有另外一種方式,叫做模型驅動(ModelDriven)。通過實現ModelDriven接口來接收請求參數,Action類必須實現ModelDriven接口,並且要重寫getModel()方法,這個方法返回的就是Action所使用的數據模型對象。 
模型驅動方式通過JavaBean模型進行數據傳遞,只要是普通的JavaBean,就可以充當模型部分。采用這種方式,JavaBean所封裝的屬性與表單的屬性一一對應,JavaBean將成為數據傳遞的載體。 
首先修改formdata.jsp頁面的內容為:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/data3.action" method="post"> username:<input type="text" name="username" /><br/> password:<input type="password" name="password" /><br/> <input type="submit" value="提交" /> </form> </body> </html>

 

然后再在cn.itcast.action.data包中創建一個Action類——Data3Action.java:

public class Data3Action extends ActionSupport implements ModelDriven<User> { // 創建實體類的對象 // 前提條件:表單輸入項的name屬性值要和實體類里面的屬性名稱一致 private User user = new User(); // 實現接口的方法 public User getModel() { // return創建的實體類的對象 return user; } @Override public String execute() throws Exception { System.out.println(user); return NONE; } }

 

注意:使用模型驅動這種方式處理請求參數的前提條件是:表單輸入項的name屬性值要和實體類里面的屬性名稱一致。 
最后在struts.xml核心配置文件中配置好該Action,如下:

<action name="data3" class="cn.itcast.action.data.Data3Action"></action>

 

這里我還要說明一點就是使用屬性封裝和使用模型驅動封裝有什么區別:

  • 使用屬性封裝,只能把數據封裝到action里面的屬性中,不能直接把數據封裝到對象里面。
  • 使用模型驅動封裝,可以直接把表單提交數據封裝到實體類對象里面。

注意的一個問題

在一個action中想要獲取同一個表單提交的數據,可以使用屬性封裝,也可以使用模型驅動封裝,但是這兩種方式不能同時使用。如果同時使用,只會使用到其中的一種,即只會使用模型驅動。示例代碼如下:

public class Data3Action extends ActionSupport implements ModelDriven<User> { // 創建實體類的對象 // 前提條件:表單輸入項的name屬性值要和實體類里面的屬性名稱一致 private User user = new User(); // 實現接口的方法 public User getModel() { // return創建的實體類的對象 return user; } // 屬性封裝 private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String execute() throws Exception { System.out.println(username + "......" + password); System.out.println(user); return NONE; } }

 

到這里我們已經能夠將數據封裝到一個Java對象中了,大部分我們會優先使用模型驅動的方式,因為Struts2內部有很多結果是圍繞模型驅動設計的。但如果頁面向多個對象中封裝,那么就需要使用屬性驅動的方式二了。這些都是向某個對象中封裝數據,那么如果Action中需要一個對象的集合呢?又應該如何進行數據的封裝呢?那么接下來我們來了解一下Struts2中復雜類型數據的封裝。

Struts2中封裝集合類型的數據

在實際的開發中,有些時候我們需要批量插入用戶或者批量插入其他對象,在Action中需要接收到這多個Action中封裝的對象,然后傳遞給業務層。那么這個時候就需要將表單的數據封裝到集合中。一般我們通常使用的集合無非是List或者Map集合。下面就以這兩種集合進行數據的封裝的示例演示。

封裝到List集合中

在WebContent目錄下編寫一個JSP頁面——list.jsp。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/list.action" method="post"> <!-- List集合的遍歷有4種方式,一種最原始的方式就是普通的for循環。 list[0]:List集合中的第一個元素,而List集合中的第一個元素是User對象的形式。 list[0].username:List集合中的第一個User對象里面的username屬性。 --> username:<input type="text" name="list[0].username" /> password:<input type="password" name="list[0].password" /><br/> username:<input type="text" name="list[1].username" /> password:<input type="password" name="list[1].password" /><br/> <input type="submit" value="提交" /> </form> </body> </html>

 

然后在cn.itcast.action.data包中創建一個Action類——ListAction.java。

public class ListAction extends ActionSupport { // List集合變量 // 在List集合中有多個User對象 private List<User> list = new ArrayList<User>(); // 生成list的set和get方法 public List<User> getList() { return list; } public void setList(List<User> list) { this.list = list; } @Override public String execute() throws Exception { System.out.println(list); for (int i = 0; i < list.size(); i++) { // List集合中的第一個元素下標是0 User user = list.get(i); } return NONE; } }

 

List集合有下標,所以可以通過list[0],list[1]。那么如果是Map集合又應該如何進行封裝呢?那么接下來我們就來看如何將數據封裝到Map集合中。

封裝數據到Map集合中

在WebContent目錄下編寫一個JSP頁面——list.jsp。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/map.action" method="post"> <!-- map['one']:設置map集合的key的值為one,得到value值是User對象 1.設置map集合的key的值為one 2.根據key得到value,value是User對象,然后向User對象里面設置值 --> username:<input type="text" name="map['one'].username" /> password:<input type="password" name="map['one'].password" /><br/> username:<input type="text" name="map['abcd'].username" /> password:<input type="password" name="map['abcd'].password" /><br/> <input type="submit" value="提交" /> </form> </body> </html>

 

然后在cn.itcast.action.data包中創建一個Action類——ListAction.java。

public class MapAction extends ActionSupport { // 1.聲明一個map變量 /** * 遍歷Map集合的兩種方式: * 1. 得到所有的key,根據key得到value * 2. 得到key-value之間的關系,使用並不多 */ private Map<String, User> map = new HashMap<String, User>(); public Map<String, User> getMap() { return map; } public void setMap(Map<String, User> map) { this.map = map; } @Override public String execute() throws Exception { System.out.println(map); return NONE; } }

 

到這兒,數據已經可以進行封裝了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM