目录
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>