Top

JAVA Struts2 DAY02

  1. 使用OGNL表达式-1
  2. 使用OGNL表达式-2
  3. 访问ValueStack-1
  4. 访问ValueStack-2
  5. 重构资费列表

1 使用OGNL表达式-1

1.1 问题

练习OGNL表达式的8种用法,即

  1. 访问基本属性
  2. 访问实体对象
  3. 访问集合/数组
  4. 访问Map
  5. 访问时运算
  6. 访问时调用方法
  7. 创建集合
  8. 创建Map

本案例中,先练习前2种用法,他们是最常用的。

1.2 方案

在一次请求当中,我们可以在页面上使用OGNL访问Action中的基本属性和实体对象属性,这里重点是关注OGNL的写法,因此案例中Action和JSP可以简化处理。

我们可以复用StrutsDay01中的HelloWorld示例,在该示例的Action中追加基本属性和实体对象,在JSP中用OGNL进行访问。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:准备项目

选中项目StrutsDay01,右键复制,如下图:

图-1

粘贴项目StrutsDay01,如下图:

图-2

在弹出框中,将项目名改为StrutsDay02,如下图:

图-3

选中StrutsDay02,右键选择Properties,如下图:

图-4

在弹出框中,将此项目的web访问地址由StrutsDay01改为StrutsDay02,如下图:

图-5

修改HelloAction,删除其他演示代码,只保留业务方法即可,代码如下:

package action;

public class HelloAction {
	
	public String sayHello() {
		return "success";
	}

}

修改hello.jsp,删除其他演示代码,只保留基本的HTML结构即可,代码如下:

<%@page pageEncoding="utf-8"%>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
</body>
</html>

此时,项目StrutsDay02的结构如下图:

图-6

部署项目,启动tomcat并访问/localhost:8088/StrutsDay02/demo/hello,效果如下图则项目准备完毕:

图-7

步骤二:使用OGNL访问Action基本属性

在HelloAction中追加任意基本属性并初始化,同时提供get、set方法,代码如下:

package action;

public class HelloAction {

#cold_bold	// 基本类型
#cold_bold	private Integer id = 1;
#cold_bold	private String name = "zhangsan";

	public String sayHello() {
		return "success";
	}

#cold_bold	public Integer getId() {
#cold_bold		return id;
#cold_bold	}
#cold_bold
#cold_bold	public void setId(Integer id) {
#cold_bold		this.id = id;
#cold_bold	}
#cold_bold
#cold_bold	public String getName() {
#cold_bold		return name;
#cold_bold	}
#cold_bold
#cold_bold	public void setName(String name) {
#cold_bold		this.name = name;
#cold_bold	}

}

在hello.jsp中,先通过taglib指令引入Struts2标签,然后在Struts2的显示标签上,使用OGNL表达式输出HelloAction中的基本属性值,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
#cold_bold	<h1>1.基本属性</h1>
#cold_bold	<h2>ID:<s:property value="id"/></h2>
#cold_bold	<h2>Name:<s:property value="name"/></h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-8

步骤三:使用OGNL访问Action实体对象属性

在HelloAction中追加实体属性并初始化,在业务方法中初始化实体对象的数据,同时提供get、set方法,代码如下:

package action;

import entity.User;

public class HelloAction {

	// 基本类型
	private Integer id = 1;
	private String name = "zhangsan";
#cold_bold	// 实体对象
#cold_bold	private User user = new User();

	public String sayHello() {
#cold_bold		// 初始化实体对象数据
#cold_bold		user.setUserName("zhangsan");
#cold_bold		user.setPassword("123456");
		return "success";
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

#cold_bold	public User getUser() {
#cold_bold		return user;
#cold_bold	}
#cold_bold
#cold_bold	public void setUser(User user) {
#cold_bold		this.user = user;
#cold_bold	}

}

hello.jsp中,在Struts2显示标签上使用OGNL表达式输出HelloAction中的实体对象值,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<h1>1.基本属性</h1>
	<h2>ID:<s:property value="id"/></h2>
	<h2>Name:<s:property value="name"/></h2>
	
#cold_bold	<h1>2.实体对象</h1>
#cold_bold	<h2>用户名:<s:property value="user.userName"/></h2>
#cold_bold	<h2>密码:<s:property value="user.password"/></h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-9

1.4 完整代码

本案例的完整代码如下。

HelloAction完整代码:

package action;

import entity.User;

public class HelloAction {

	// 基本类型
	private Integer id = 1;
	private String name = "zhangsan";
	// 实体对象
	private User user = new User();

	public String sayHello() {
		// 初始化实体对象数据
		user.setUserName("zhangsan");
		user.setPassword("123456");
		return "success";
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

}

Hello.jsp完整代码:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<h1>1.基本属性</h1>
	<h2>ID:<s:property value="id"/></h2>
	<h2>Name:<s:property value="name"/></h2>
	
	<h1>2.实体对象</h1>
	<h2>用户名:<s:property value="user.userName"/></h2>
	<h2>密码:<s:property value="user.password"/></h2>
	
</body>
</html>

2 使用OGNL表达式-2

2.1 问题

练习使用OGNL表达式的后6种用法,即

  1. 访问集合/数组
  2. 访问Map
  3. 访问时运算
  4. 访问时调用方法
  5. 创建集合
  6. 创建Map

相对于前2种用法,这些用法不是很常用,同学们以了解为主。

2.2 方案

在项目StrutsDay02基础上,使用OGNL表达式的后6种用法访问HelloAction中的属性值。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:Action中准备数据

由于用法较多,比较繁琐,我们一次性在Action中准备好页面要访问的全部数据,这样就不用反复重启tomcat了。即在HelloAction中准备如下类型的数据:集合、数组、Map,代码如下:

package action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import entity.User;

public class HelloAction {

	// 基本类型
	private Integer id = 1;
	private String name = "zhangsan";
	// 实体对象
	private User user = new User();
#cold_bold	// 数组和集合
#cold_bold	private String[] cityArray = new String[] { "beijing", "shanghai", "guangzhou" };
#cold_bold	private List<String> cityList = new ArrayList<String>();
#cold_bold	// Map
#cold_bold	private Map<String, String> cityMap = new HashMap<String, String>();

	public String sayHello() {
		// 初始化实体对象数据
		user.setUserName("zhangsan");
		user.setPassword("123456");
#cold_bold		// 初始化集合数据
#cold_bold		cityList.add("shenzhen");
#cold_bold		cityList.add("chongqing");
#cold_bold		cityList.add("qingdao");
#cold_bold		// 初始化Map数据
#cold_bold		cityMap.put("beijing", "2300万人口");
#cold_bold		cityMap.put("shanghai", "2000万人口");
#cold_bold		cityMap.put("guangzhou", "1800万人口");
		
		return "success";
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

#cold_bold	public String[] getCityArray() {
#cold_bold		return cityArray;
#cold_bold	}
#cold_bold
#cold_bold	public void setCityArray(String[] cityArray) {
#cold_bold		this.cityArray = cityArray;
#cold_bold	}
#cold_bold
#cold_bold	public List<String> getCityList() {
#cold_bold		return cityList;
#cold_bold	}
#cold_bold
#cold_bold	public void setCityList(List<String> cityList) {
#cold_bold		this.cityList = cityList;
#cold_bold	}
#cold_bold
#cold_bold	public Map<String, String> getCityMap() {
#cold_bold		return cityMap;
#cold_bold	}
#cold_bold
#cold_bold	public void setCityMap(Map<String, String> cityMap) {
#cold_bold		this.cityMap = cityMap;
#cold_bold	}

}

步骤二:访问集合/数组

hello.jsp中,在Struts2显示标签上使用OGNL表达式输出HelloAction中的数组和集合属性值,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
<!—此处略去其他表达式的演示... -->	
#cold_bold	<h1>3.数组和集合</h1>
#cold_bold	<h2>数组中的城市:<s:property value="cityArray[1]"/></h2>
#cold_bold	<h2>集合中的城市:<s:property value="cityList[1]"/></h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-10

步骤三:访问Map

hello.jsp中,在Struts2显示标签上使用OGNL表达式输出HelloAction中的Map属性值,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<!—此处略去其他表达式的演示... -->
	
#cold_bold	<h1>4.Map</h1>
#cold_bold	<h2>Map中的城市人口:<s:property value="cityMap.beijing"/></h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-11

步骤四:访问时进行运算

hello.jsp中,在Struts2显示标签上使用OGNL表达式输出HelloAction中的任意属性值,同时可以在OGNL表达式中对返回结果进行运算,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<!—此处略去其他表达式的演示... -->
	
#cold_bold	<h1>5.访问时运算</h1>
#cold_bold	<h2>My Name:<s:property value="'My name is '+name"/></h2>
#cold_bold	<h2>去哪:<s:property value="cityArray[1]+',我来了!'"/></h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-12

步骤五:访问时调用方法

hello.jsp中,在Struts2显示标签上使用OGNL表达式输出HelloAction中的任意属性值,同时可以在OGNL中调用返回值的方法,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<!—此处略去其他表达式的演示... -->
	
#cold_bold	<h1>6.访问时调用方法</h1>
#cold_bold	<h2>MY NAME:<s:property value="name.toUpperCase()"/></h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-13

步骤六:创建集合

hello.jsp中,在Struts2显示标签上使用OGNL表达式创建一个临时的集合并输出,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<!—此处略去其他表达式的演示... -->
	
#cold_bold	<h1>7.创建集合</h1>
#cold_bold	<h2>创建集合:<s:property value="{'a','b','c'}"/></h2>
#cold_bold	<h2>集合类型:<s:property value="{'a','b','c'}.getClass().getName()"/></h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-14

步骤七:创建Map

hello.jsp中,在Struts2显示标签上使用OGNL表达式创建一个临时的Map并输出,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<!—此处略去其他表达式的演示... -->
	
#cold_bold	<h1>8.创建Map</h1>
#cold_bold	<h2>创建Map:<s:property value="#{'mm':'MM','nn':'NN'}"/></h2>
#cold_bold	<h2>
#cold_bold		Map类型:<s:property value="#{'mm':'MM','nn':'NN'}.getClass().getName()"/>
#cold_bold	</h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-15

2.4 完整代码

本案例的完整代码如下。

HelloAction完整代码:

package action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import entity.User;

public class HelloAction {

	// 基本类型
	private Integer id = 1;
	private String name = "zhangsan";
	// 实体对象
	private User user = new User();
	// 数组和集合
	private String[] cityArray = new String[] { "beijing", "shanghai", "guangzhou" };
	private List<String> cityList = new ArrayList<String>();
	// Map
	private Map<String, String> cityMap = new HashMap<String, String>();

	public String sayHello() {
		// 初始化实体对象数据
		user.setUserName("zhangsan");
		user.setPassword("123456");
		// 初始化集合数据
		cityList.add("shenzhen");
		cityList.add("chongqing");
		cityList.add("qingdao");
		// 初始化Map数据
		cityMap.put("beijing", "2300万人口");
		cityMap.put("shanghai", "2000万人口");
		cityMap.put("guangzhou", "1800万人口");
		
		return "success";
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String[] getCityArray() {
		return cityArray;
	}

	public void setCityArray(String[] cityArray) {
		this.cityArray = cityArray;
	}

	public List<String> getCityList() {
		return cityList;
	}

	public void setCityList(List<String> cityList) {
		this.cityList = cityList;
	}

	public Map<String, String> getCityMap() {
		return cityMap;
	}

	public void setCityMap(Map<String, String> cityMap) {
		this.cityMap = cityMap;
	}

}

hello.jsp完整代码:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<h1>1.基本属性</h1>
	<h2>ID:<s:property value="id"/></h2>
	<h2>Name:<s:property value="name"/></h2>
	
	<h1>2.实体对象</h1>
	<h2>用户名:<s:property value="user.userName"/></h2>
	<h2>密码:<s:property value="user.password"/></h2>
	
	<h1>3.数组和集合</h1>
	<h2>数组中的城市:<s:property value="cityArray[1]"/></h2>
	<h2>集合中的城市:<s:property value="cityList[1]"/></h2>
	
	<h1>4.Map</h1>
	<h2>Map中的城市人口:<s:property value="cityMap.beijing"/></h2>
	
	<h1>5.访问时运算</h1>
	<h2>My Name:<s:property value="'My name is '+name"/></h2>
	<h2>去哪:<s:property value="cityArray[1]+',我来了!'"/></h2>
	
	<h1>6.访问时调用方法</h1>
	<h2>MY NAME:<s:property value="name.toUpperCase()"/></h2>
	
	<h1>7.创建集合</h1>
	<h2>创建集合:<s:property value="{'a','b','c'}"/></h2>
	<h2>集合类型:<s:property value="{'a','b','c'}.getClass().getName()"/></h2>
	
	<h1>8.创建Map</h1>
	<h2>创建Map:<s:property value="#{'mm':'MM','nn':'NN'}"/></h2>
	<h2>
		Map类型:<s:property value="#{'mm':'MM','nn':'NN'}.getClass().getName()"/>
	</h2>
	
</body>
</html>

其他代码不变,不再重复。

3 访问ValueStack-1

3.1 问题

在页面上,使用Struts2标签和OGNL表达式观察ValueStack的结构,并访问ValueStack中栈对象和Context对象的数据,包括如下内容

  1. 观察ValueStack结构
  2. 输出栈顶内容
  3. 输出Context对象中的数据
  4. 遍历集合
  5. 按数字迭代

本案例中,我们先练习前3个知识点。

3.2 方案

复用项目StrutsDay02,在hello.jsp上写Struts2标签和OGNL表达式观察并访问ValueStack。

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:观察ValueStack结构

在hello.jsp上增加<s:debug/>标签,通过该标签来观察ValueStack结构,代码如下图:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<!—此处略去OGNL表达式的演示... -->
	
#cold_bold	<!-- ValueStack示例 -->
#cold_bold	<h1>1.观察ValueStack结构</h1>
#cold_bold	<h2><s:debug/></h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-16

步骤二:输出栈顶内容

在hello.jsp上,使用Struts2标签输出栈顶的内容,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<!—此处略去OGNL表达式的演示... -->
	
	<!-- ValueStack示例 -->
	
	<h1>1.观察ValueStack结构</h1>
	<h2><s:debug/></h2>
	
#cold_bold	<h1>2.栈顶</h1>
#cold_bold	<h2>Stack Top:<s:property/></h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-17

步骤三:输出Context对象中的数据

hello.jsp中,在Struts2显示标签上使用OGNL输出ValueStack中Context对象的值,表达式格式为“#key”,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<!—此处略去OGNL表达式的演示... -->
	
	<!-- ValueStack示例 -->
	
	<h1>1.观察ValueStack结构</h1>
	<h2><s:debug/></h2>
	
	<h1>2.栈顶</h1>
	<h2>Stack Top:<s:property/></h2>
	
#cold_bold	<h1>3.输出context对象中的数据</h1>
#cold_bold	<h2>context:<s:property value="#action.user.userName"/></h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-18

3.4 完整代码

本案例的完整代码如下。

hello.jsp完整代码:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<h1>1.基本属性</h1>
	<h2>ID:<s:property value="id"/></h2>
	<h2>Name:<s:property value="name"/></h2>
	
	<h1>2.实体对象</h1>
	<h2>用户名:<s:property value="user.userName"/></h2>
	<h2>密码:<s:property value="user.password"/></h2>
	
	<h1>3.数组和集合</h1>
	<h2>数组中的城市:<s:property value="cityArray[1]"/></h2>
	<h2>集合中的城市:<s:property value="cityList[1]"/></h2>
	
	<h1>4.Map</h1>
	<h2>Map中的城市人口:<s:property value="cityMap.beijing"/></h2>
	
	<h1>5.访问时运算</h1>
	<h2>My Name:<s:property value="'My name is '+name"/></h2>
	<h2>去哪:<s:property value="cityArray[1]+',我来了!'"/></h2>
	
	<h1>6.访问时调用方法</h1>
	<h2>MY NAME:<s:property value="name.toUpperCase()"/></h2>
	
	<h1>7.创建集合</h1>
	<h2>创建集合:<s:property value="{'a','b','c'}"/></h2>
	<h2>集合类型:<s:property value="{'a','b','c'}.getClass().getName()"/></h2>
	
	<h1>8.创建Map</h1>
	<h2>创建Map:<s:property value="#{'mm':'MM','nn':'NN'}"/></h2>
	<h2>
		Map类型:<s:property value="#{'mm':'MM','nn':'NN'}.getClass().getName()"/>
	</h2>
	
	<!-- ValueStack示例 -->
	
	<h1>1.观察ValueStack结构</h1>
	<h2><s:debug/></h2>
	
	<h1>2.栈顶</h1>
	<h2>Stack Top:<s:property/></h2>
	
	<h1>3.输出context对象中的数据</h1>
	<h2>context:<s:property value="#action.user.userName"/></h2>
	
</body>
</html>

其他代码不变,不再重复。

4 访问ValueStack-2

4.1 问题

练习使用ValueStack,即:

  1. 遍历集合
  2. 按数字迭代

4.2 方案

复用项目StrutsDay02,在hello.jsp上写Struts2标签和OGNL表达式,练习迭代集合以及按数字进行迭代。

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:遍历集合

在HelloAction中追加集合属性并实例化,同时提供get、set方法,在业务方法中初始化集合的数据,代码如下:

package action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import entity.Emp;
import entity.User;

public class HelloAction {

	// 基本类型
	private Integer id = 1;
	private String name = "zhangsan";
	// 实体对象
	private User user = new User();
	// 数组和集合
	private String[] cityArray = new String[] { "beijing", "shanghai", "guangzhou" };
	private List<String> cityList = new ArrayList<String>();
	// Map
	private Map<String, String> cityMap = new HashMap<String, String>();
	
#cold_bold	// 员工集合
#cold_bold	private List<Emp> emps = new ArrayList<Emp>();

	public String sayHello() {
		// 初始化实体对象数据
		user.setUserName("zhangsan");
		user.setPassword("123456");
		// 初始化集合数据
		cityList.add("shenzhen");
		cityList.add("chongqing");
		cityList.add("qingdao");
		// 初始化Map数据
		cityMap.put("beijing", "2300万人口");
		cityMap.put("shanghai", "2000万人口");
		cityMap.put("guangzhou", "1800万人口");
#cold_bold		// 初始化员工数据
#cold_bold		Emp e1 = new Emp();
#cold_bold		e1.setEmpName("刘备");
#cold_bold		e1.setSalary(8000.0);
#cold_bold		emps.add(e1);
#cold_bold		Emp e2 = new Emp();
#cold_bold		e2.setEmpName("关羽");
#cold_bold		e2.setSalary(6000.0);
#cold_bold		emps.add(e2);
#cold_bold		Emp e3 = new Emp();
#cold_bold		e3.setEmpName("张飞");
#cold_bold		e3.setSalary(5000.0);
#cold_bold		emps.add(e3);
		
		return "success";
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String[] getCityArray() {
		return cityArray;
	}

	public void setCityArray(String[] cityArray) {
		this.cityArray = cityArray;
	}

	public List<String> getCityList() {
		return cityList;
	}

	public void setCityList(List<String> cityList) {
		this.cityList = cityList;
	}

	public Map<String, String> getCityMap() {
		return cityMap;
	}

	public void setCityMap(Map<String, String> cityMap) {
		this.cityMap = cityMap;
	}

#cold_bold	public List<Emp> getEmps() {
#cold_bold		return emps;
#cold_bold	}
#cold_bold
#cold_bold	public void setEmps(List<Emp> emps) {
#cold_bold		this.emps = emps;
#cold_bold	}

}

在hello.jsp中,使用迭代标签遍历上述集合属性,并输出集合中变量emp的属性值,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<!—此处略去OGNL表达式的演示... -->
	
	<!-- ValueStack示例 -->
	
	<h1>1.观察ValueStack结构</h1>
	<h2><s:debug/></h2>
	
	<h1>2.栈顶</h1>
	<h2>Stack Top:<s:property/></h2>
	
	<h1>3.输出context对象中的数据</h1>
	<h2>context:<s:property value="#action.user.userName"/></h2>
	
#cold_bold	<h1>4.遍历集合</h1>
#cold_bold	<h2>
#cold_bold		<!--迭代标签,遍历集合 -->
#cold_bold		<s:iterator value="emps">
#cold_bold			<!-- 
#cold_bold				迭代过程中,栈顶为Emp对象,
#cold_bold				写OGNL输出其属性值。
#cold_bold			 -->
#cold_bold			员工:<s:property value="empName"/>,
#cold_bold			工资为<s:property value="salary"/><br/>
#cold_bold		</s:iterator>
#cold_bold	</h2>
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-19

步骤二:按数字迭代

在HelloAction中追加迭代的起止值并实例化,同时提供get、set方法,代码如下:

package action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import entity.Emp;
import entity.User;

public class HelloAction {

	// 基本类型
	private Integer id = 1;
	private String name = "zhangsan";
	// 实体对象
	private User user = new User();
	// 数组和集合
	private String[] cityArray = new String[] { "beijing", "shanghai", "guangzhou" };
	private List<String> cityList = new ArrayList<String>();
	// Map
	private Map<String, String> cityMap = new HashMap<String, String>();
	
	// 员工集合
	private List<Emp> emps = new ArrayList<Emp>();
#cold_bold	//迭代数字的起止值
#cold_bold	private Integer from = 1;
#cold_bold	private Integer to = 3;

	public String sayHello() {
		// 初始化实体对象数据
		user.setUserName("zhangsan");
		user.setPassword("123456");
		// 初始化集合数据
		cityList.add("shenzhen");
		cityList.add("chongqing");
		cityList.add("qingdao");
		// 初始化Map数据
		cityMap.put("beijing", "2300万人口");
		cityMap.put("shanghai", "2000万人口");
		cityMap.put("guangzhou", "1800万人口");
		// 初始化员工数据
		Emp e1 = new Emp();
		e1.setEmpName("刘备");
		e1.setSalary(8000.0);
		emps.add(e1);
		Emp e2 = new Emp();
		e2.setEmpName("关羽");
		e2.setSalary(6000.0);
		emps.add(e2);
		Emp e3 = new Emp();
		e3.setEmpName("张飞");
		e3.setSalary(5000.0);
		emps.add(e3);
		
		return "success";
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String[] getCityArray() {
		return cityArray;
	}

	public void setCityArray(String[] cityArray) {
		this.cityArray = cityArray;
	}

	public List<String> getCityList() {
		return cityList;
	}

	public void setCityList(List<String> cityList) {
		this.cityList = cityList;
	}

	public Map<String, String> getCityMap() {
		return cityMap;
	}

	public void setCityMap(Map<String, String> cityMap) {
		this.cityMap = cityMap;
	}

	public List<Emp> getEmps() {
		return emps;
	}

	public void setEmps(List<Emp> emps) {
		this.emps = emps;
	}

#cold_bold	public Integer getFrom() {
#cold_bold		return from;
#cold_bold	}
#cold_bold
#cold_bold	public void setFrom(Integer from) {
#cold_bold		this.from = from;
#cold_bold	}
#cold_bold
#cold_bold	public Integer getTo() {
#cold_bold		return to;
#cold_bold	}
#cold_bold
#cold_bold	public void setTo(Integer to) {
#cold_bold		this.to = to;
#cold_bold	}

}

在hello.jsp中,使用迭代标签按照HelloAction中的起止值循环,并输出循环变量的值,代码如下:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<!—此处略去OGNL表达式的演示... -->
	
	<!-- ValueStack示例 -->
	
	<h1>1.观察ValueStack结构</h1>
	<h2><s:debug/></h2>
	
	<h1>2.栈顶</h1>
	<h2>Stack Top:<s:property/></h2>
	
	<h1>3.输出context对象中的数据</h1>
	<h2>context:<s:property value="#action.user.userName"/></h2>
	
	<h1>4.遍历集合</h1>
	<h2>
		<!--迭代标签,遍历集合 -->
		<s:iterator value="emps">
			<!-- 
				迭代过程中,栈顶为Emp对象,
				写OGNL输出其属性值。
			 -->
			员工:<s:property value="empName"/>,
			工资为<s:property value="salary"/><br/>
		</s:iterator>
	</h2>
	
#cold_bold	<h1>5.循环数字</h1>
#cold_bold	<h2>
#cold_bold		<!--迭代标签,按数字迭代 -->
#cold_bold		<s:iterator begin="from" end="to" var="p">
#cold_bold			<!-- 
#cold_bold				迭代过程中,栈顶为数字,但不能以数字为root写OGNL。
#cold_bold				此时可以声明变量p,通过Context对象实现对变量的访问。
#cold_bold			 -->
#cold_bold			<s:property value="#p"/>
#cold_bold		</s:iterator>
#cold_bold	</h2>		
	
</body>
</html>

重新部署StrutsDay02并启动tomcat后,访问StrutsDay02,效果如下图:

图-20

4.4 完整代码

本案例的完整代码如下所示:

HelloAction完整代码

package action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import entity.Emp;
import entity.User;

public class HelloAction {

	// 基本类型
	private Integer id = 1;
	private String name = "zhangsan";
	// 实体对象
	private User user = new User();
	// 数组和集合
	private String[] cityArray = new String[] { "beijing", "shanghai", "guangzhou" };
	private List<String> cityList = new ArrayList<String>();
	// Map
	private Map<String, String> cityMap = new HashMap<String, String>();
	
	// 员工集合
	private List<Emp> emps = new ArrayList<Emp>();
	//迭代数字的起止值
	private Integer from = 1;
	private Integer to = 3;

	public String sayHello() {
		// 初始化实体对象数据
		user.setUserName("zhangsan");
		user.setPassword("123456");
		// 初始化集合数据
		cityList.add("shenzhen");
		cityList.add("chongqing");
		cityList.add("qingdao");
		// 初始化Map数据
		cityMap.put("beijing", "2300万人口");
		cityMap.put("shanghai", "2000万人口");
		cityMap.put("guangzhou", "1800万人口");
		// 初始化员工数据 
		Emp e1 = new Emp();
		e1.setEmpName("刘备");
		e1.setSalary(8000.0);
		emps.add(e1);
		Emp e2 = new Emp();
		e2.setEmpName("关羽");
		e2.setSalary(6000.0);
		emps.add(e2);
		Emp e3 = new Emp();
		e3.setEmpName("张飞");
		e3.setSalary(5000.0);
		emps.add(e3);
		
		return "success";
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String[] getCityArray() {
		return cityArray;
	}

	public void setCityArray(String[] cityArray) {
		this.cityArray = cityArray;
	}

	public List<String> getCityList() {
		return cityList;
	}

	public void setCityList(List<String> cityList) {
		this.cityList = cityList;
	}

	public Map<String, String> getCityMap() {
		return cityMap;
	}

	public void setCityMap(Map<String, String> cityMap) {
		this.cityMap = cityMap;
	}

	public List<Emp> getEmps() {
		return emps;
	}

	public void setEmps(List<Emp> emps) {
		this.emps = emps;
	}

	public Integer getFrom() {
		return from;
	}

	public void setFrom(Integer from) {
		this.from = from;
	}

	public Integer getTo() {
		return to;
	}

	public void setTo(Integer to) {
		this.to = to;
	}

}

hello.jsp完整代码:

<%@page pageEncoding="utf-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
</head>
<body>
	<h1>演示OGNL表达式</h1>
	
	<h1>1.基本属性</h1>
	<h2>ID:<s:property value="id"/></h2>
	<h2>Name:<s:property value="name"/></h2>
	
	<h1>2.实体对象</h1>
	<h2>用户名:<s:property value="user.userName"/></h2>
	<h2>密码:<s:property value="user.password"/></h2>
	
	<h1>3.数组和集合</h1>
	<h2>数组中的城市:<s:property value="cityArray[1]"/></h2>
	<h2>集合中的城市:<s:property value="cityList[1]"/></h2>
	
	<h1>4.Map</h1>
	<h2>Map中的城市人口:<s:property value="cityMap.beijing"/></h2>
	
	<h1>5.访问时运算</h1>
	<h2>My Name:<s:property value="'My name is '+name"/></h2>
	<h2>去哪:<s:property value="cityArray[1]+',我来了!'"/></h2>
	
	<h1>6.访问时调用方法</h1>
	<h2>MY NAME:<s:property value="name.toUpperCase()"/></h2>
	
	<h1>7.创建集合</h1>
	<h2>创建集合:<s:property value="{'a','b','c'}"/></h2>
	<h2>集合类型:<s:property value="{'a','b','c'}.getClass().getName()"/></h2>
	
	<h1>8.创建Map</h1>
	<h2>创建Map:<s:property value="#{'mm':'MM','nn':'NN'}"/></h2>
	<h2>
		Map类型:<s:property value="#{'mm':'MM','nn':'NN'}.getClass().getName()"/>
	</h2>
	
	<!-- ValueStack示例 -->
	<h1>1.观察ValueStack结构</h1>
	<h2><s:debug/></h2>
	
	<h1>2.栈顶</h1>
	<h2>Stack Top:<s:property/></h2>
	
	<h1>3.输出context对象中的数据</h1>
	<h2>context:<s:property value="#action.user.userName"/></h2>
	
	<h1>4.遍历集合</h1>
	<h2>
		<!-- 迭代标签,遍历集合 -->
		<s:iterator value="emps">
			<!-- 
				迭代过程中,栈顶为Emp对象,
				写OGNL输出其属性值。
			 -->
			员工:<s:property value="empName"/>,
			工资为<s:property value="salary"/><br/>
		</s:iterator>
	</h2>
	
	<h1>5.循环数字</h1>
	<h2>
		<!-- 迭代标签,按数字迭代 -->
		<s:iterator begin="from" end="to" var="p">
			<!-- 
				迭代过程中,栈顶为数字,但不能以数字为root写OGNL。
				此时可以声明变量p,通过Context对象实现对变量的访问。
			 -->
			<s:property value="#p"/>
		</s:iterator>
	</h2>		
	
</body>
</html>

5 重构资费列表

5.1 问题

我们已经学会了使用Struts2标签+OGNL表达式访问ValueStack,从而访问到Action中的数据,那么请使用该手段重构NetCTOSS资费列表页面find_cost.jsp,将该页面上的JSTL标签+EL表达式重构为Struts2标签+OGNL表达式。

5.2 方案

使用Struts2的迭代标签及OGNL表达式重构find_cost.jsp。

5.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:重构资费列表页面

重构find_cost.jsp,将其中的JSTL标签+EL表达式替换成Struts2标签+OGNL表达式,代码如下:

<%@page pageEncoding="utf-8" isELIgnored="false"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="/www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link type="text/css" rel="stylesheet" media="all" href="../styles/global.css" />
<link type="text/css" rel="stylesheet" media="all" href="../styles/global_color.css" />
<script language="javascript" type="text/javascript">
            //排序按钮的点击事件
function sort(btnObj) {
if (btnObj.className == "sort_desc")
                    btnObj.className = "sort_asc";
else
                    btnObj.className = "sort_desc";
            }

            //启用
function startFee() {
                var r = window.confirm("确定要启用此资费吗?资费启用后将不能修改和删除。");
document.getElementById("operate_result_info").style.display = "block";
            }
            //删除
function deleteFee(id) {
                var r = window.confirm("确定要删除此资费吗?");
if(r) {
	// 如果用户确认,则调用删除资费action
	window.location.href = "deleteCost?id="+id;
                }
            }
</script>
</head>
<body>
<!--Logo区域开始-->
<div id="header">
<img src="../images/logo.png" alt="logo" class="left"/>
<a href="#">[退出]</a>
</div>
<!--Logo区域结束-->
<!--导航区域开始-->
<div id="navi">
<ul id="menu">
<li><a href="../index.html" class="index_off"></a></li>
<li><a href="../role/role_list.html" class="role_off"></a></li>
<li><a href="../admin/admin_list.html" class="admin_off"></a></li>
<li><a href="../fee/fee_list.html" class="fee_on"></a></li>
<li><a href="../account/account_list.html" class="account_off"></a></li>
<li><a href="../service/service_list.html" class="service_off"></a></li>
<li><a href="../bill/bill_list.html" class="bill_off"></a></li>
<li><a href="../report/report_list.html" class="report_off"></a></li>
<li><a href="../user/user_info.html" class="information_off"></a></li>
<li><a href="../user/user_modi_pwd.html" class="password_off"></a></li>
</ul>
</div>
<!--导航区域结束-->
<!--主要区域开始-->
<div id="main">
<form action="" method="">
<!--排序-->
<div class="search_add">
<div>
<!--<input type="button" value="月租" class="sort_asc" onclick="sort(this);" />-->
<input type="button" value="基费" class="sort_asc" onclick="sort(this);" />
<input type="button" value="时长" class="sort_asc" onclick="sort(this);" />
</div>
<input type="button" value="增加" class="btn_add" onclick="location.href='toAddCost';" />
</div>
<!--启用操作的操作提示-->
<div id="operate_result_info" class="operate_success">
<img src="../images/close.png" onclick="this.parentNode.style.display='none';" />
删除成功!
</div>
<!--数据区域:用表格展示数据-->
<div id="data">
<table id="datalist">
<tr>
<th>资费ID</th>
<th class="width100">资费名称</th>
<th>基本时长</th>
<th>基本费用</th>
<th>单位费用</th>
<th>创建时间</th>
<th>开通时间</th>
<th class="width50">状态</th>
<th class="width200"></th>
</tr>

#cold_bold<!--使用Struts2标签遍历集合,使用OGNL表达式输出内容。 -->
#cold_bold<s:iterator value="costs">
#cold_bold	<tr>
#cold_bold	<td><s:property value="id"/></td>
#cold_bold	<td><a href="fee_detail.html"><s:property value="name"/></a></td>
#cold_bold	<td><s:property value="baseDuration"/></td>
#cold_bold	<td><s:property value="baseCost"/></td>
#cold_bold	<td><s:property value="unitCost"/></td>
#cold_bold	<td><s:property value="createTime"/></td>
#cold_bold	<td><s:property value="startTime"/></td>
#cold_bold	<td>
#cold_bold		<s:if test="status==0">开通</s:if>
#cold_bold		<s:else>暂停</s:else>
#cold_bold	</td>
#cold_bold	<td>
#cold_bold	<input type="button" value="启用" class="btn_start" onclick="startFee();" />
#cold_bold	<input type="button" value="修改" class="btn_modify" onclick="location.href='toUpdateCost?id=<s:property value="id"/>';" />
#cold_bold	<input type="button" value="删除" class="btn_delete" onclick="deleteFee(<s:property value="id"/>);" />
#cold_bold	</td>
#cold_bold	</tr>
#cold_bold</s:iterator>

</table>
<p>业务说明:<br />
                    1、创建资费时,状态为暂停,记载创建时间;<br />
                    2、暂停状态下,可修改,可删除;<br />
                    3、开通后,记载开通时间,且开通后不能修改、不能再停用、也不能删除;<br />
                    4、业务账号修改资费时,在下月底统一触发,修改其关联的资费ID(此触发动作由程序处理)
</p>
</div>
<!--分页-->
<div id="pages">
	<a href="#">上一页</a>
<a href="#" class="current_page">1</a>
<a href="#">2</a>
<a href="#">3</a>
<a href="#">4</a>
<a href="#">5</a>
<a href="#">下一页</a>
</div>
</form>
</div>
<!--主要区域结束-->
<div id="footer">
<p>[源自北美的技术,最优秀的师资,最真实的企业环境,最适用的实战项目]</p>
<p>版权所有(C)</p>
</div>
</body>
</html>

重新部署并启动tomcat,访问资费列表页面,效果如下图:

图-21

5.4 完整代码

本案例的完整代码如下。

find_cost.jsp完整代码:

<%@page pageEncoding="utf-8" isELIgnored="false"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="/www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link type="text/css" rel="stylesheet" media="all" href="../styles/global.css" />
<link type="text/css" rel="stylesheet" media="all" href="../styles/global_color.css" />
<script language="javascript" type="text/javascript">
            //排序按钮的点击事件
function sort(btnObj) {
if (btnObj.className == "sort_desc")
                    btnObj.className = "sort_asc";
else
                    btnObj.className = "sort_desc";
            }

            //启用
function startFee() {
                var r = window.confirm("确定要启用此资费吗?资费启用后将不能修改和删除。");
document.getElementById("operate_result_info").style.display = "block";
            }
            //删除
function deleteFee(id) {
                var r = window.confirm("确定要删除此资费吗?");
if(r) {
	// 如果用户确认,则调用删除资费action
	window.location.href = "deleteCost?id="+id;
                }
            }
</script>
</head>
<body>
<!--Logo区域开始-->
<div id="header">
<img src="../images/logo.png" alt="logo" class="left"/>
<a href="#">[退出]</a>
</div>
<!--Logo区域结束-->
<!--导航区域开始-->
<div id="navi">
<ul id="menu">
<li><a href="../index.html" class="index_off"></a></li>
<li><a href="../role/role_list.html" class="role_off"></a></li>
<li><a href="../admin/admin_list.html" class="admin_off"></a></li>
<li><a href="../fee/fee_list.html" class="fee_on"></a></li>
<li><a href="../account/account_list.html" class="account_off"></a></li>
<li><a href="../service/service_list.html" class="service_off"></a></li>
<li><a href="../bill/bill_list.html" class="bill_off"></a></li>
<li><a href="../report/report_list.html" class="report_off"></a></li>
<li><a href="../user/user_info.html" class="information_off"></a></li>
<li><a href="../user/user_modi_pwd.html" class="password_off"></a></li>
</ul>
</div>
<!--导航区域结束-->
<!--主要区域开始-->
<div id="main">
<form action="" method="">
<!--排序-->
<div class="search_add">
<div>
<!--<input type="button" value="月租" class="sort_asc" onclick="sort(this);" />-->
<input type="button" value="基费" class="sort_asc" onclick="sort(this);" />
<input type="button" value="时长" class="sort_asc" onclick="sort(this);" />
</div>
<input type="button" value="增加" class="btn_add" onclick="location.href='toAddCost';" />
</div>
<!--启用操作的操作提示-->
<div id="operate_result_info" class="operate_success">
<img src="../images/close.png" onclick="this.parentNode.style.display='none';" />
                    删除成功!
</div>
<!--数据区域:用表格展示数据-->
<div id="data">
<table id="datalist">
<tr>
<th>资费ID</th>
<th class="width100">资费名称</th>
<th>基本时长</th>
<th>基本费用</th>
<th>单位费用</th>
<th>创建时间</th>
<th>开通时间</th>
<th class="width50">状态</th>
<th class="width200"></th>
</tr>

<!-- 使用Struts2标签遍历集合,使用OGNL表达式输出内容。 -->
<s:iterator value="costs">
	<tr>
	<td><s:property value="id"/></td>
	<td><a href="fee_detail.html"><s:property value="name"/></a></td>
	<td><s:property value="baseDuration"/></td>
	<td><s:property value="baseCost"/></td>
	<td><s:property value="unitCost"/></td>
	<td><s:property value="createTime"/></td>
	<td><s:property value="startTime"/></td>
	<td>
		<s:if test="status==0">开通</s:if>
		<s:else>暂停</s:else>
	</td>
	<td>
	<input type="button" value="启用" class="btn_start" onclick="startFee();" />
	<input type="button" value="修改" class="btn_modify" onclick="location.href='toUpdateCost?id=<s:property value="id"/>';" />
	<input type="button" value="删除" class="btn_delete" onclick="deleteFee(<s:property value="id"/>);" />
	</td>
	</tr>
</s:iterator>

</table>
<p>业务说明:<br />
                    1、创建资费时,状态为暂停,记载创建时间;<br />
                    2、暂停状态下,可修改,可删除;<br />
                    3、开通后,记载开通时间,且开通后不能修改、不能再停用、也不能删除;<br />
                    4、业务账号修改资费时,在下月底统一触发,修改其关联的资费ID(此触发动作由程序处理)
</p>
</div>
<!--分页-->
<div id="pages">
	<a href="#">上一页</a>
<a href="#" class="current_page">1</a>
<a href="#">2</a>
<a href="#">3</a>
<a href="#">4</a>
<a href="#">5</a>
<a href="#">下一页</a>
</div>
</form>
</div>
<!--主要区域结束-->
<div id="footer">
<p>[源自北美的技术,最优秀的师资,最真实的企业环境,最适用的实战项目]</p>
<p>版权所有(C) </p>
</div>
</body>
</html>

其他代码不变,不再重复。