Action接受请求参数
作为MVC框架,必须要负责解析HTTP请求参数,并将其封装到Model对象中
Struts2提供了非常强大的类型转换机制用于请求数据 到 model对象的封装
Struts2提供了非常强大的类型转换机制用于请求数据 到 model对象的封装
Struts2和MVC定义关系
StrutsPrepareAndExecuteFilter:控制器
在Struts2中action是什么?(Struts2是一个MVC框架)
V:jsp
M:action
C:action StrutsPrepareAndExecuteFilter
Struts2提供了三种数据封装方式:
- Action本身作为model对象,通过成员setter封装。(属于属性驱动)
- 创建独立model对象,页面通过ognl表达式封装。(属于属性驱动)
- 使用ModelDrivern接口,对请求数据进行封装。(属于模型驱动)
具体使用如下:
1.属性驱动
属性驱动方式(一):直接将action作为一个model,就可以得到请求参数
action类成员变量setter接收参数如下图所示:
问题1:action封装请求参数,会不会存在线程安全问题?
是不会的,因为每一次请求,都是一个新的action
优点:使用简单
缺点:需要单独定义JavaBean,将action中属性copy到JavaBean中(不能将Action作为model传给service层)
这种方式,底层是通过反射进行实现的。
属性驱动方式(二):创建一个单独的Model类,在action类中引用model作为成员变量。(页面使用ognl)
具体操作:
在action类中声明一个mdoel,private User user;
提供对应的setter和getter方法。
在页面上使用ognl来进行描述
<input type="text" name="user.username"> 如下图所示:
这种方式的优点:简单易使用,解决了第一种封装的问题。
缺点:在页面上使用了ognl表达式,页面不通用了。
问题:这种方式,数据是怎样封装的?
是通过Struts2中name为params的interceptor拦截器进行的数据封装(Struts的核心core包下struts-default.xml中定义)<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
2.模型驱动(在开发中应用比较多)
模型驱动的步骤:
1.让action 类实现ModelDrivern接口。
2.重写getModel方法
3.在action中实例化一个model对象,让getModel方法返回这个对象。
public class Login3Action extends ActionSupport implements ModelDriven<User> {
private User user = new User();
public User getModel() {
return user;
}
}
private User user = new User();
public User getModel() {
return user;
}
}
如下图所示:
优点:解决了属性驱动存在的问题
缺点:一次只能封装一个model对象
Struts2有很多围绕模型驱动的属性(在struts-default.xml中的拦截器中定义)
<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
扩展:
(1)将数据封装到List集合。类型转换与Collection配合使用。
Struts2还允许填充Collection里的对象,这常见于需要快速录入批量数据的场合。
页面:
username1:<input type="text" name="users[0].username"><br>
password1:<input type="password" name="users[0].password"><br>
username2:<input type="text" name="users[1].username"><br>
password2:<input type="password" name="users[1].password"><br>
action类:
private List<User> users;
get/set方法
username1:<input type="text" name="users[0].username"><br>
password1:<input type="password" name="users[0].password"><br>
username2:<input type="text" name="users[1].username"><br>
password2:<input type="password" name="users[1].password"><br>
action类:
private List<User> users;
get/set方法
(2)将数据封装到Map集合(类型转换与Map配合使用)
页面:
username1:<input type="text" name="map['aaa'].username"><br>
password1:<input type="password" name="map['aaa'].password"><br>
username2:<input type="text" name="map['bbb'].username"><br>
password2:<input type="password" name="map['bbb'].password"><br>
username1:<input type="text" name="map['aaa'].username"><br>
password1:<input type="password" name="map['aaa'].password"><br>
username2:<input type="text" name="map['bbb'].username"><br>
password2:<input type="password" name="map['bbb'].password"><br>
action类:
private Map<String, User> map;
提供get/set
示例:
1.将action作为model(属性驱动方式一)
Login1Action
package cn.itcast.action;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
// 获取请求参数 属性驱动 第一种,直接将action作为model
public class Login1Action extends ActionSupport {
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 {
HttpServletRequest request = ServletActionContext.getRequest();
// 2.判断用户名与密码是否正确
if ("tom".equals(username) && "123".equals(password)) {
request.getSession().setAttribute("username", username);
return SUCCESS;
} else {
request.setAttribute("login.message", "用户名或密码错误");
return "failer";
}
}
}
login1.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>
${requestScope["login.message"]}
<br>
<form action="${pageContext.request.contextPath}/login1" method="POST">
username:<input type="text" name="username"><br>
password:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
2.将model对象作为Action类成员(属性驱动模式二)
封装Model类
User
package cn.itcast.domain;
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 + "]";
}
}
Login2Action
package cn.itcast.action;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import cn.itcast.domain.User;
import com.opensymphony.xwork2.ActionSupport;
// 获取请求参数 属性驱动 第二种,直接在action上声明一个model
public class Login2Action extends ActionSupport {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
// 2.判断用户名与密码是否正确
if ("tom".equals(user.getUsername())
&& "123".equals(user.getPassword())) {
request.getSession().setAttribute("username", user.getUsername());
return SUCCESS;
} else {
request.setAttribute("login.message", "用户名或密码错误");
return "failer";
}
}
}
login2.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>
${requestScope["login.message"]}
<br>
<form action="${pageContext.request.contextPath}/login2" method="POST">
username:<input type="text" name="user.username"><br>
password:<input type="password" name="user.password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
3.模型驱动(action类实现ModelDrivern接口)
Login3Action
package cn.itcast.action;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import cn.itcast.domain.User;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
// 获取请求参数 模型驱动
public class Login3Action extends ActionSupport implements ModelDriven<User> {
private User user=new User();
@Override
public User getModel() {
return user;
}
@Override
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
// 2.判断用户名与密码是否正确
if ("tom".equals(user.getUsername())
&& "123".equals(user.getPassword())) {
request.getSession().setAttribute("username", user.getUsername());
return SUCCESS;
} else {
request.setAttribute("login.message", "用户名或密码错误");
return "failer";
}
}
}
login3.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>
${requestScope["login.message"]}
<br>
<form action="${pageContext.request.contextPath}/login3" method="POST">
username:<input type="text" name="username"><br>
password:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
success.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>
${username }
</body>
</html>
4.将数据封装到List集合
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"