练习OGNL表达式的8种用法,即
本案例中,先练习前2种用法,他们是最常用的。
在一次请求当中,我们可以在页面上使用OGNL访问Action中的基本属性和实体对象属性,这里重点是关注OGNL的写法,因此案例中Action和JSP可以简化处理。
我们可以复用StrutsDay01中的HelloWorld示例,在该示例的Action中追加基本属性和实体对象,在JSP中用OGNL进行访问。
实现此案例需要按照如下步骤进行。
步骤一:准备项目
选中项目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并访问http://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
本案例的完整代码如下。
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>
练习使用OGNL表达式的后6种用法,即
相对于前2种用法,这些用法不是很常用,同学们以了解为主。
在项目StrutsDay02基础上,使用OGNL表达式的后6种用法访问HelloAction中的属性值。
实现此案例需要按照如下步骤进行。
步骤一: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
本案例的完整代码如下。
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>
其他代码不变,不再重复。
在页面上,使用Struts2标签和OGNL表达式观察ValueStack的结构,并访问ValueStack中栈对象和Context对象的数据,包括如下内容
本案例中,我们先练习前3个知识点。
复用项目StrutsDay02,在hello.jsp上写Struts2标签和OGNL表达式观察并访问ValueStack。
实现此案例需要按照如下步骤进行。
步骤一:观察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
本案例的完整代码如下。
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>
其他代码不变,不再重复。
练习使用ValueStack,即:
复用项目StrutsDay02,在hello.jsp上写Struts2标签和OGNL表达式,练习迭代集合以及按数字进行迭代。
实现此案例需要按照如下步骤进行。
步骤一:遍历集合
在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
本案例的完整代码如下所示:
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>
我们已经学会了使用Struts2标签+OGNL表达式访问ValueStack,从而访问到Action中的数据,那么请使用该手段重构NetCTOSS资费列表页面find_cost.jsp,将该页面上的JSTL标签+EL表达式重构为Struts2标签+OGNL表达式。
使用Struts2的迭代标签及OGNL表达式重构find_cost.jsp。
实现此案例需要按照如下步骤进行。
步骤一:重构资费列表页面
重构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" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>达内-NetCTOSS</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)加拿大达内IT培训集团公司</p> </div> </body> </html>
重新部署并启动tomcat,访问资费列表页面,效果如下图:
图-21
本案例的完整代码如下。
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" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>达内-NetCTOSS</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)加拿大达内IT培训集团公司 </p> </div> </body> </html>
其他代码不变,不再重复。