目錄
Action獲取表單數據的方式
在使用servlet處理請求的過程中,可以通過request對象獲得表單提交過來的數據。採用struts2後將採用Action處理請求,而Action類中並沒有request對象,所以不能直接使用request對象獲取表單提交的數據。以下將講解如何在Action中獲取表單提交的數據。
Action獲取表單提交的數據主要有三種方式:
(1)使用ActionContext類
(2)使用ServletActionContext類
(3)使用接口注入方式
通過ActionContext類獲取
在Struts2中,提供了ActionContext類來訪問Servlet API,ActionContext是Action執行的上下文對象,在ActionContext中保存了Action執行所需要的所有對象,包括parameters、request、session、application等。在主要講解ActionContext中的一個方法:getParameters()
,它用來返回一個包含所有HttpServletRequest參數信息的Map集合。
案例:
form1.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>ActionContext接收表單數據</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/form1.action" method="post">
用戶名:<input type="text" name="username"/><br/>
密 碼:<input type="password" name="password"/><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
Form1Action.java
package com.wm103.form;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import java.util.Set;
public class Form1Action extends ActionSupport {
@Override
public String execute() throws Exception {
// 1. 獲取ActionContext對象
ActionContext context = ActionContext.getContext();
// 2. 獲取表單數據,其中Map集合中的key是表單name的屬性值,value是對應表單輸入項的值
Map<String, Object> parameters = context.getParameters();
Set<String> keys = parameters.keySet();
for (String key: keys) {
// 這裏是數組形式的原因是一個表單name屬性值可以對應多個value值,如複選框提交數據
Object[] obj = (Object[]) parameters.get(key);
System.out.println(key + ": " + Arrays.toString(obj));
}
return NONE;
}
}
struts.xml中的配置:
<package name="demo2" extends="struts-default" namespace="/">
<action name="form1" class="com.wm103.form.Form1Action"></action>
</package>
使用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中的靜態方法getRequest獲取request對象。如:
Form2Action.java
package com.wm103.form;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import javax.servlet.http.HttpServletRequest;
public class Form2Action extends ActionSupport {
@Override
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username + ": " + password);
return NONE;
}
}
通過特定接口訪問
(這種方式一般不使用。)
爲了在Action中直接訪問Servlet API,Stuts2還提供了一系列接口,具體如下:
- ServletRequestAware:實現該接口的Action可以直接訪問Web應用的HttpServletRequest實例;
- ServletResponseAware:實現該接口的Action可以直接訪問Web應用的HttpServletResponse實例;
- SessionAware:實現該接口的Action可以直接訪問Web應用的HttpSession實例;
- ServletContextAware:實現該接口的Action可以直接訪問Web應用的ServletContext實例。
這裏爲獲取表單數據,需要Action實現ServletRequestAction接口,如:
Form3Action.java
package com.wm103.form;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.interceptor.ServletRequestAware;
import javax.servlet.http.HttpServletRequest;
public class Form3Action extends ActionSupport implements ServletRequestAware {
private HttpServletRequest request;
@Override
public void setServletRequest(HttpServletRequest httpServletRequest) {
this.request = httpServletRequest;
}
@Override
public String execute() throws Exception {
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username + ": " + password);
return NONE;
}
}
在Action中操作域對象
在Servlet中有3個域對象,分別爲 request、session和servletContext。(pageContext域對象[page域]是在JSP中的)。
使用ServletActionContext操作域對象,如:
DomainAction.java
package com.wm103.action;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class DomainAction extends ActionSupport {
@Override
public String execute() throws Exception {
// 1. 獲取request域對象
HttpServletRequest request = ServletActionContext.getRequest();
request.setAttribute("request", "requestValue");
// 2. 獲取session域對象
HttpSession session = request.getSession();
session.setAttribute("session", "sessionValue");
// 3. 獲取servletContext域對象
ServletContext servletContext = ServletActionContext.getServletContext();
servletContext.setAttribute("servletContext", "servletContextValue");
return NONE;
}
}
Action中原始方式封裝表單數據
通過ServletActionContext對象獲取request對象,進而使用request對象獲取表單數據,將數據到的數據封裝到實體對象去。如:
實體類 User.java
package com.wm103.entity;
/**
* Created by DreamBoy on 2017/5/26.
*/
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 + '\'' +
'}';
}
}
Form4Action.java
package com.wm103.form;
import com.opensymphony.xwork2.ActionSupport;
import com.wm103.entity.User;
import org.apache.struts2.ServletActionContext;
import javax.servlet.http.HttpServletRequest;
/**
* Created by DreamBoy on 2017/5/26.
*/
public class Form4Action extends ActionSupport {
@Override
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = new User();
user.setUsername(username);
user.setPassword(password);
System.out.println(user);
return NONE;
}
}
Struts2中表單數據的封裝
在實際開發中,我們需要在Action獲取到表單數據,並對錶單數據進行封裝,封裝到一個JavaBean中,然後將JavaBean傳遞給業務層。這些封裝的操作Struts2框架提供了實現方式。如下。
屬性封裝
在Struts2中可以直接在Action中定義各種Java基本數據類型的字段,使這些字段與表單數據相對應,並利用這些字段進行數據傳遞。
實現步驟如下:
(1)在Action成員變量中定義變量,且變量名稱與表單輸入項的name屬性值一致;
(2)在Action中生成與這些變量對應的set方法。
案例如下:
Data1Action.java
package com.wm103.data;
import com.opensymphony.xwork2.ActionSupport;
public class Data1Action extends ActionSupport {
// 1. 定義變量,且變量的名稱與表單輸入項中的name屬性值一致
private String username;
private String password;
// 2. 生成變量對應的set方法(這裏把getter和setter方法都生成了)
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(this.username + ": " + this.password);
return NONE;
}
}
注:使用屬性封裝只能獲取表單數據到Action屬性中,並不能把數據直接封裝到實體類對象裏面。
模型驅動封裝(重點)
使用模型驅動封裝的方式,我們可以直接把表單數據封裝到實體類對象。
模型驅動:通過實現ModelDriven接口來接收請求參數,Action類必須實現ModelDriven接口,並且要重寫getModel()方法,這個方法返回的就是Action所使用的數據模型對象。
實現步驟:
(1)讓Action類實現接口ModelDriven;
(2)在Action類中創建實體類對象成員;
(3)實現接口中getModel方法,並返回上述提及的實體類對象。
案例如下:
Data2Action.java
package com.wm103.data;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.wm103.entity.User;
public class Data2Action extends ActionSupport implements ModelDriven<User> {
// 創建實體類對象
// 注意:要求表單輸入項的name屬性值與實體類屬性名稱一致,否則表單數據無法封裝到實體對象的屬性中去。
private User user = new User();
@Override
public User getModel() {
return user;
}
@Override
public String execute() throws Exception {
System.out.println(this.user.getUsername() + ": " + this.user.getPassword());
return NONE;
}
}
使用模型驅動和屬性封裝時需要注意的問題:
在一個Action中,獲取表單數據可以使用屬性封裝,也可以使用模型驅動封裝,但是不能同時使用這兩種方式獲取同一個表單數據。如果同時使用,那麼將執行模型驅動封裝數據。
表達式封裝
使用表達式封裝也可以把表單數據封裝到實體類對象中去。表達式封裝也可以歸類於屬性封裝。
實現步驟:
(1)在Action中聲明實體類對象;
(2)在Action中爲該實體類對象生成實體類變量的set和get方法;
(3)在表單中提交項的name屬性值中寫表達式形式,表達式的內容爲 實體類對象的名稱.實體類對象的屬性名
。
案例如下:
Data3Action.java
package com.wm103.data;
import com.opensymphony.xwork2.ActionSupport;
import com.wm103.entity.User;
public class Data3Action extends ActionSupport {
// 1. 聲明實體類對象
private User user;
// 2. 生成實體類變量的set和get方法
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {
System.out.println(this.user);
return NONE;
}
}
在struts.xml中Action的配置:
<package name="demo2" extends="struts-default" namespace="/">
<action name="data3" class="com.wm103.data.Data3Action"></action>
</package>
測試頁面 data3.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>表達式封裝</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/data3.action" method="post">
用戶名:<input type="text" name="user.username"/><br/>
密 碼:<input type="password" name="user.password"/><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
比較表達式封裝和模型驅動封裝
- 相同點:使用表達式封裝和模型驅動封裝都可以把數據封裝到實體類對象中。
- 不同點:
- 使用模型驅動只能把數據封裝到一個實體類對象中。在一個Action中不能使用模型驅動把數據封裝到不同的實體類對象裏面。
- 使用表達式封裝可以把數據封裝到不同的實體類對象中。
Struts2封裝數據到集合中
封裝數據到List集合
將表單提交的數據存儲到List集合中,實現步驟如下(類似表達式封裝):
(1)在Action中聲明List集合對象;
(2)在該Action中生成List對象的get和set方法;
(3)在表單的提交項name屬性中填寫表達式,表達式的格式爲 List集合對象的名稱[下標].List集合中存儲的對象的屬性名稱
。
案例如下:
ListAction.java
package com.wm103.data;
import com.opensymphony.xwork2.ActionSupport;
import com.wm103.entity.User;
import java.util.List;
public class ListAction extends ActionSupport {
private List<User> list;
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);
return NONE;
}
}
在struts.xml中Action的配置:
<package name="demo2" extends="struts-default" namespace="/">
<action name="list" class="com.wm103.data.ListAction"></action>
</package>
list.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>封裝數據到List集合</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/list.action" method="post">
用戶名1:<input type="text" name="list[0].username"/><br/>
密 碼1:<input type="password" name="list[0].password"/><br/>
<br/><br/>
用戶名2:<input type="text" name="list[1].username"/><br/>
密 碼2:<input type="password" name="list[1].password"/><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
封裝數據到Map集合
將表單提交的數據存儲到Map集合中,實現步驟如下(類似表達式封裝):
(1)在Action中聲明Map集合對象;
(2)在該Action中生成Map對象的get和set方法;
(3)在表單的提交項name屬性中填寫表達式,表達式的格式爲 Map集合對象的名稱['自定義鍵值對的key值'].Map集合中存儲的對象的屬性名稱
。
案例如下:
MapAction.java
package com.wm103.data;
import com.opensymphony.xwork2.ActionSupport;
import com.wm103.entity.User;
import java.util.Map;
public class MapAction extends ActionSupport {
private Map<String, User> map;
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;
}
}
在struts.xml中Action的配置:
<package name="demo2" extends="struts-default" namespace="/">
<action name="map" class="com.wm103.data.MapAction"></action>
</package>
map.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>封裝數據到Map集合</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/map.action" method="post">
用戶名1:<input type="text" name="map['key01'].username"/><br/>
密 碼1:<input type="password" name="map['key01'].password"/><br/>
<br/><br/>
用戶名2:<input type="text" name="map['key02'].username"/><br/>
密 碼2:<input type="password" name="map['key02'].password"/><br/>
<input type="submit" value="提交">
</form>
</body>
</html>