结果页面配置
全局结果页面
1 、result标签配置action方法的返回值到不同的路径里面
2、 创建两个action,执行默认的方法execute方法,让两个action的方法都返回success,返回success之后,配置到同一个页面里面
(1)如果多个action,方法里面返回值相同的,到页面也是相同的,这个时候可以使用全局结果页面配置
<?xml version="1.0" encoding="UTF-8"?>
<package name="demo1" extends="struts-default" namespace="/">
<action name="book" class="com.struct2_stu.action.BookAction">
<result name="success">/hello.jsp</result>
<result name="success">/hello.jsp</result>
</action>
</package>
(2)在package标签里面配置
<?xml version="1.0" encoding="UTF-8"?>
<package name="demo1" extends="struts-default" namespace="/">
<!-- 全局结果页面配置 -->
<!-- 只是在当前package生效 -->
<global-results>
<result name="success">/hello.jsp</result>
</global-results>
</package>
局部结果页面
既有全局结果页面也有局部结果页面时,以局部配置为准
<?xml version="1.0" encoding="UTF-8"?>
<package name="demo1" extends="struts-default" namespace="/">
<!-- 全局结果页面配置 -->
<!-- 只是在当前package生效 -->
<global-results>
<result name="success">/hello.jsp</result>
</global-results>
<action name="book" class="com.struct2_stu.action.BookAction">
<result name="success">/world.jsp</result>
</action>
</package>
Result标签的type属性
1 result标签里面除了name属性之外,还有一个属性 type属性
(1)type属性:如何到路径里面(转发还是重定向)
2 type属性值
(1)默认值,做转发操作,值是 dispatcher
地址值不变,只有一次请求,做的是转发操作
(2)做重定向操作,值是 redirect
<result name="success" type="redirect">/hello.jsp</result>
地址值变化,两次请求,做的是重定向操作
(2)上面两个值dispatcher、redirect,这两个值一般针对到页面中配置,
配置到其他的action里面
- chain:转发到action,一般不用,缓存问题

- redirectAction:重定向到action(重要)
<?xml version="1.0" encoding="UTF-8"?>
package name="demo1" extends="struts-default" namespace="/">
<action name="book" class="com.struct2_stu.action.BookAction">
<!-- 重定向action,当访问book,返回success时,会请求重定向到orders.action -->
<result name="success" type="redirectAction">orders</result>
<!--转发到orders.action(一般不用,有缓存问题) -->
<result name="success" type="chain">orders</result>
</action>
</package>
Action获取表单提交数据(重要)
1 、之前web阶段,提交表单到servlet里面,在servlet里面使用request对象里面的方法获取,getParameter,getParameterMap
2 、提交表单到action,但是action没有request对象,不能直接使用request对象
3、 action获取表单提交数据主要三种方式
(1)使用ActionContext类
(2)使用ServletActionContext类(重要)
(3)使用接口注入方式使用ActionContext类获取
使用方法:
(1)因为方法不是静态的方法,需要创建ActionContext类的对象
(2)这个ActionContext类对象不是new出来的,

1 、具体演示
(1)创建表单,提交表单到action里面
创建表单:
<%@ 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}/from1.action" method="post">
username:<input type="text" name="username"/>
<br/>
password:<input type="password" name="password"/>
<br/>
address:<input type="text" name="address"/>
<br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
表单样式:
创建action:
<package name="demo2" extends="struts-default" namespace="/">
<action name="from1" class="com.struct2_stu.from.From1DemoAction"></action>
</package>
(2)在action使用ActionContext获取数据
package com.struct2_stu.from;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
* 使用ActionContext的有点是可以很好的解耦合,类中无需从request获取对象而是从context对象获取
* @author hhh
*
*/
public class From1DemoAction extends ActionSupport {
public String execute(){
//使用ActionContext类
//1、获取ActionContext对象
ActionContext context = ActionContext.getContext();
//2、调用getParameters获取表单数据
//key是表单输入项的name属性值,value是表单输入的值
Map<String, Object> map = context.getParameters();
Set<String> keys =map.keySet();
for (String key : keys) {
//value是数组形式,因为输入项里面可能有复选框的情况,复选框有多个值
Object[] value=(Object[]) map.get(key);
System.out.println(Arrays.toString(value));
}
return NONE;
}
}
使用ServletActionContext类获取(重点)
(1)创建的from表单与action配置与ActionContext相同
(2)调用类里面静态方法,得到request对象

package com.struct2_stu.from;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class From2DemoAction extends ActionSupport {
public String execute() {
// 使用servletActionContext类获取
// 1、获取request对象
HttpServletRequest request = ServletActionContext.getRequest();
// 调用request内方法得到结果
String username = request.getParameter("username");
String password = request.getParameter("password");
String address = request.getParameter("address");
System.out.println(username+" "+password+" "+address);
return NONE;
}
}
使用接口注入(了解)
1 、让action实现接口,为了得到request对象package com.struct2_stu.from;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
* 使用接口注入
* @author hhh
*
*/
public class From3DemoAction extends ActionSupport implements ServletRequestAware{
private HttpServletRequest request;
public String execute(){
String username=request.getParameter("username");
String password=request.getParameter("password");
String address=request.getParameter("address");
return NONE;
}
@Override
public void setServletRequest(HttpServletRequest request) {
this.request=request;
}
}
在action操作域对象
1 、request、session、servletContext域对象
-request域,在开发中,传输数据到页面,request对象用的最多
-session域,session常用于保持登陆状态
-servletContext域, 在开发中servletContext域对象用的很少,
2、 使用ServletActionContext类操作

package com.struct2_stu.from;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
*在action中如何操作域对象
* @author hhh
*
*/
public class From4DemoAction extends ActionSupport {
public String execute(){
//演示操作三个域对象,request,session,servletContext
HttpServletRequest request = ServletActionContext.getRequest();
//request域,在开发中,传输数据到页面,request对象用的最多
request.setAttribute("req", "reqvalue");
//session域,session用于保持登陆状态
HttpSession session = request.getSession();
session.setAttribute("session", "sessionvalue");
//servletContext域, 在开发中servletContext域对象用的很少,
ServletContext context = ServletActionContext.getServletContext();
context.setAttribute("conrtext", "contextValue");
return NONE;
}
}
Struts2封装获取表单数据方式(重点)
原始方式获取表单封装到实体类对象
使用的是原始的创建对象,然后使用实体类的set方法将属性值存储到对象中
package com.struct2_stu.from;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.struct2_stu.entity.User;
/**
* 原始方法:较为麻烦
*使用ServletActionContext获取表单数据,将表单数据封装到实体类对象中
* @author hhh
*
*/
public class EntityAction extends ActionSupport{
@Override
public String execute() throws Exception {
//得到表单数据
HttpServletRequest request = ServletActionContext.getRequest();
String username=request.getParameter("username");
String password=request.getParameter("password");
String address=request.getParameter("address");
//将得到的数据封装到书体类对象中
User user = new User();
user.setUsername(username);
user.setPassword(password);
user.setAddress(address);
System.out.println(user);
return NONE;
}
}
属性封装(会用)
1、 直接把表单提交属性封装到action的属性里面
2、 实现步骤
(1)在action成员变量位置定义变量
- 变量名称和表单输入项的name属性值一样
(2)生成变量的set方法(把set和get方法都写出来)
3、 使用属性封装获取表单数据到属性里面,不能把数据直接封装到实体类对象里面
package com.struct2_stu.data;
import com.opensymphony.xwork2.ActionSupport;
/**
* 使用属性封装获取表单数据
*
* @author hhh
*
*/
public class DataDemo1Action extends ActionSupport {
// 定义变量,变量名称要与表单输入项的name属性值一致
private String username;
private String password;
private String address;
//生成变量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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String execute() {
System.out.println(username+" "+password+" "+address);
return NONE;
}
}
模型驱动封装(重点)
1 、使用模型驱动方式,可以直接把表单数据封装到实体类对象里面,前提要求:表单输入项目的name属性值和实体类属性值名称要一致
2、 实现步骤
(1)action实现接口 ModelDriven

(2)实现接口里面的方法 getModel方法
- 把创建对象返回
(3)在action里面创建实体类对象
package com.struct2_stu.entity;
public class User {
private String username;
private String password;
private String address;
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password
+ ", address=" + address + "]";
}
}
3 、使用模型驱动和属性封装注意问题(重点):
(1)在一个action中,获取表单数据可以属性封装,也使用模型驱动封装,
-不能同时使用属性封装和模型驱动封装获取同一个表单数据
-如果同时使用,之后执行模型驱动表达式封装(会用)
1、 实现过程
(1)使用表达式封装可以把表单数据封装到实体类对象里面
第一步 在action里面声明实体类
第二步 生成实体类变量的set和get方法
package com.struct2_stu.data;
import com.opensymphony.xwork2.ActionSupport;
import com.struct2_stu.entity.Book;
import com.struct2_stu.entity.User;
/**
* 使用表达式形式进行封装数据
*
* @author hhh
*
*/
public class DataDemo3Action extends ActionSupport {
//声明实体类
private User user;
//生成get与set方法
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute() {
System.out.println(user);
System.out.println(book.getBname());
return NONE;
}
}
第三步 在表单输入项的name属性值里面写表达式形式,把表达式封装归类到属性封装里面
<form action="${pageContext.request.contextPath}/data3.action" method="post">
<!--会去action类中找到getUSer方法找到对象,user.username会调用setUser方法设置对象, -->
username:<input type="text" name="user.username"/>
<br/>
password:<input type="password" name="user.password"/>
<br/>
address:<input type="text" name="user.address"/>
<br/>
<input type="submit" value="提交"/>
比较表达式封装和模型驱动封装(重点)
1 、使用表达式封装和模型驱动封装都可以把数据封装到实体类对象里面
2 、不同点:
(1)使用模型驱动只能把数据封装到一个实体类对象里面
- 在一个action里面不能使用模型驱动把数据封装到不同的实体类对象里面
(2)使用表达式封装可以把数据封装到不同的实体类对象里面
演示表达式封装将数据封装到不同实体类:
package com.struct2_stu.data;
import com.opensymphony.xwork2.ActionSupport;
import com.struct2_stu.entity.Book;
import com.struct2_stu.entity.User;
/**
* 使用表达式形式进行封装数据,封装到多个对象
*
* @author hhh
*
*/
public class DataDemo3Action extends ActionSupport {
//声明实体类
private User user;
private Book book;
//生成get与set方法
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute() {
System.out.println(user);
System.out.println(book.getBname());
return NONE;
}
}
在jsp中,将数据设置到不同对象中
<form action="${pageContext.request.contextPath}/data3.action" method="post">
<!--会去action类中找到getUSer方法找到对象,user.username会调用setUser方法设置对象, -->
username:<input type="text" name="user.username"/>
<br/>
password:<input type="password" name="user.password"/>
<br/>
address:<input type="text" name="user.address"/>
<br/>
bnema:<input type="text" name="book.bname"/>
<input type="submit" value="提交"/>
封装到集合里面
封装数据到List集合
第一步 在action声明List
第二步 生成list变量的set和get方法
package com.struct2_stu.listandmap;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
import com.struct2_stu.entity.User;
/**
* 封装数据到list集合中
* @author hhh
*
*/
public class ListAction extends ActionSupport{
private List<User> list;
//生成get与set
public List<User> getList() {
return list;
}
public void setList(List<User> list) {
this.list = list;
}
public String execute(){
System.out.println(list);
return NONE;
}
}
第三步 在表单输入项里面写表达式
<form action="${pageContext.request.contextPath}/list.action" method="post">
<!-- 多个user效果 ,表单数据提交,数据会被存储到list集合中-->
<!-- list[0]表示list集合中的第一个user对象 -->
username:<input type="text" name="list[0].username"/>
<br/>
password:<input type="password" name="list[0].password"/>
<br/>
address:<input type="text" name="list[0].address"/>
<br/><br/>
username:<input type="text" name="list[1].username"/>
<br/>
password:<input type="password" name="list[1].password"/>
<br/>
address:<input type="text" name="list[1].address"/>
<br/>
<input type="submit" value="提交"/>
</form>
封装数据到Map集合
第一步 声明map集合
第二步 生成get和set方法
package com.struct2_stu.listandmap;
import java.util.List;
import java.util.Map;
import com.opensymphony.xwork2.ActionSupport;
import com.struct2_stu.entity.User;
/**
* 封装数据到list集合中
* @author hhh
*
*/
public class MapAction extends ActionSupport{
private Map<String,User> map;
//生成get与set
public Map<String, User> getMap() {
return map;
}
public void setMap(Map<String, User> map) {
this.map = map;
}
public String execute(){
System.out.println(map);
return NONE;
}
}
第三步 在表单输入项的name属性值里面写表达式
<form action="${pageContext.request.contextPath}/map.action" method="post">
<!-- 设置key值,设置value -->
username:<input type="text" name="map['one'].username"/>
<br/>
password:<input type="password" name="map['one'].password"/>
<br/>
address:<input type="text" name="map['one'].address"/>
<br/><br/>
username:<input type="text" name="map['abc'].username"/>
<br/>
password:<input type="password" name="map['abc'].password"/>
<br/>
address:<input type="text" name="map['abc'].address"/>
<br/>
<input type="submit" value="提交"/>
</form>
案例-添加客户功能
1 、模型驱动获取表单数据

2 、在hibernate实现

3 、添加之后到列表页面中,让列表的action执行一次

本章小结:
1、 结果页面配置
(1)全局结果页面
(2)局部结果页面
- 配置全局也配置局部,最终局部为准
(3)result标签type属性
- 默认值 dispatcher做转发
- redirect做重定向
- chain:转发到action
- redirectAction:重定向到action
2、在action获取表单提交数据
(1)使用ActionContext类获取
(2)使用ServletActionContext类获取
(3)使用接口注入方式获取
- 使用ServletActionContext类操作域对象
3 、struts2提供获取表单数据方式
(1)属性封装
- 定义变量,变量和表单输入项name属性值一样,生成get和set方法
(2)模型驱动封装(重点)
- 实现接口,实现接口里面的方法,表单输入项name属性值和实体类属性名称一样
(3)表达式封装
(4)表达式封装和模型驱动封装比较
- 相同点:可以把数据封装到实体类对象里面
- 不同点:表达式封装可以封装到不同的实体类里面
4 、struts2获取数据封装到集合中(会用)
(1)封装到list集合
(2)封装到map集合
5、 案例-添加客户功能