1.关于 值栈
1).helloworld 时,${productName} 读取productName 值,实际上该属性不在request 等域对象中,而是从值栈中获取的。
2).valueStack:可以从ActionContext 中获取值栈对象,值栈分为两个逻辑部门,
> Map 栈( ContextMap ):实际上是OgnlContext 类型,是一个Map,也是多ActionContext的一个引用。里面保存着各种MaprequsetMap,sessionMap,parameterMap,applicationMap,attr
Struts 会把下面这些映射压入 ContextMap 中
parameters: 该 Map 中包含当前请求的请求参数
request: 该 Map 中包含当前 request 对象中的所有属性
session: 该 Map 中包含当前 session 对象中的所有属性
application:该 Map 中包含当前 application 对象中的所有属性
attr: 该 Map 按如下顺序来检索某个属性: request, session, application
> 对象栈( ObjectStack ):实际是CompoundRoot类型,是一个使用了ArrayList定义的栈,里面保存着和当前Action实例相关的对象。是一个数据结构意义的栈
ValueStack(值栈): 贯穿整个 Action 的生命周期(每个 Action 类的对象实例都拥有一个 ValueStack 对象). 相当于一个数据的中转站. 在其中保存当前 Action 对象和其他相关对象.
Struts 框架把 ValueStack 对象保存在名为 “struts.valueStack” 的请求属性中
2.OGNL
1)在 JSP 页面上可以可以利用 OGNL(Object-Graph Navigation Language: 对象-图导航语言) 访问到值栈(ValueStack) 里的对象属性.
2)若希望访问值栈中 ContextMap 中的数据, 需要给 OGNL 表达式加上一个前缀字符 #. 如果没有前缀字符 #, 搜索将在 ObjectStack 里进行.
3)Struts2利用s:property 标签和OGNL 表达式来读取值栈中的属性值
>对于对象栈:读取的是对象栈中的某一个对象的属性值
>map栈:request,session,application 的一个属性值 或 一个请求参数的值
①读取对象栈中的对象的属性:
>若想访问 Object Stack 里面某个对象的属性。可以使用一下几种形式之一:
推荐第一种: object.propertyName; object['propertyName']; object["propertyName"];
>ObjectStack 里的对象可以通过一个从零开始的下标来引用. ObjectStack 里的栈顶对象可以用 [0] 来引用,它下面的那个对象可以用 [1] 引用.
[0].message
>[n] 的含义从第n 个开始搜索,而不只是搜索第n 个对象
>若从栈顶对象开始搜索,则可以省略下标部门:message
>结合s:property 标签: 等同
注意:默认情况下,Action对象会被Struts2 自动的放到值栈的栈顶
1
2 pageEncoding="UTF-8"%>
3 导入标签库
4
5
6
7
8
detail page9
10
11
12
13
14 ProductName:${productName }
15
16 ProductDesc:${productDesc }
17
18
19 ProductPrice: //使用标签进行访问值栈
20
21
22
23
24
25
Product.java
1 package com.jason.struts2;
2
3 import com.opensymphony.xwork2.ActionContext;
4 import com.opensymphony.xwork2.util.ValueStack;
5
6 public class Product {
7
8 private Integer productId;
9 private String productName;
10 private String productDesc;
11
12 private double productPrice;
13
14
15
16 public String save(){
17
18 System.out.println(this);
19 //1.获取值栈
20 ValueStack valueStack = ActionContext.getContext().getValueStack();
21
22 //2.创建 Test 对象,并对其赋值
23 Test test = new Test();
24 test.setProductDesc("testProductDesc");
25 test.setProductName("testProductName");
26
27 //3.把Test 对象压入 值栈的栈顶
28 valueStack.push(test);
29
30 return "success";
31 }
32
33
34 @Override
35 public String toString() {
36 return "Product [productId=" + productId + ", productName="
37 + productName + ", productDesc=" + productDesc
38 + ", productPrice=" + productPrice + "]";
39 }
40
41 public Integer getProductId() {
42 return productId;
43 }
44
45 public void setProductId(Integer productId) {
46 this.productId = productId;
47 }
48
49 public String getProductName() {
50 return productName;
51 }
52
53 public void setProductName(String productName) {
54 this.productName = productName;
55 }
56
57 public String getProductDesc() {
58 return productDesc;
59 }
60
61 public void setProductDesc(String productDesc) {
62 this.productDesc = productDesc;
63 }
64
65 public double getProductPrice() {
66 return productPrice;
67 }
68
69 public void setProductPrice(double productPrice) {
70 this.productPrice = productPrice;
71 }
72
73
74
75
76 }
Test.java
1 package com.jason.struts2;
2
3 public class Test {
4 private String productName;
5 private String productDesc;
6 public String getProductName() {
7 return productName;
8 }
9 public void setProductName(String productName) {
10 this.productName = productName;
11 }
12 public String getProductDesc() {
13 return productDesc;
14 }
15 public void setProductDesc(String productDesc) {
16 this.productDesc = productDesc;
17 }
18
19
20 }
struts.xml
1 <?xml version="1.0" encoding="UTF-8" ?>
2 /p>
3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
4 "http://struts.apache.org/dtds/struts-2.3.dtd">
5
6
7
8
9
10
11 /details.jsp
12
13
14
15
16
② 读取 Context Map 里的对象的属性
>若想访问 ContextMap 里的某个对象的属性, 可以使用以下几种形式之一
推荐第一种: #object.propertyName; #object['propertyName']; #object["propertyName"];
>示例:
返回 session 中的 code 属性: #session.code
返回 request 中的 customer 属性的 name 属性值: #request.customer.name
返回域对象(按 request, session, application 的顺序)的 lastAccessDate 属性: #attr.lastAccessDate
Product.java
1 package com.jason.struts2;
2
3 import java.util.Map;
4
5 import org.apache.struts2.interceptor.RequestAware;
6 import org.apache.struts2.interceptor.SessionAware;
7
8 import com.opensymphony.xwork2.ActionContext;
9 import com.opensymphony.xwork2.util.ValueStack;
10
11 public class Product implements RequestAware,SessionAware{
12
13 private Integer productId;
14 private String productName;
15 private String productDesc;
16 private double productPrice;
17
18
19
20 public String save(){
21
22 System.out.println(this);
23 //1.获取值栈
24 ValueStack valueStack = ActionContext.getContext().getValueStack();
25
26 //2.创建 Test 对象,并对其赋值
27 Test test = new Test();
28 test.setProductDesc("testProductDesc");
29 test.setProductName("testProductName");
30
31 //3.把Test 对象压入 值栈的栈顶
32 valueStack.push(test);
33 sessionMap.put("product", this);
34 requestMap.put("test", test);
35
36 return "success";
37 }
38
39
40 @Override
41 public String toString() {
42 return "Product [productId=" + productId + ", productName="
43 + productName + ", productDesc=" + productDesc
44 + ", productPrice=" + productPrice + "]";
45 }
46
47 public Integer getProductId() {
48 return productId;
49 }
50
51 public void setProductId(Integer productId) {
52 this.productId = productId;
53 }
54
55 public String getProductName() {
56 return productName;
57 }
58
59 public void setProductName(String productName) {
60 this.productName = productName;
61 }
62
63 public String getProductDesc() {
64 return productDesc;
65 }
66
67 public void setProductDesc(String productDesc) {
68 this.productDesc = productDesc;
69 }
70
71 public double getProductPrice() {
72 return productPrice;
73 }
74
75 public void setProductPrice(double productPrice) {
76 this.productPrice = productPrice;
77 }
78
79
80 private Map sessionMap;
81 public void setSession(Map arg0) {
82 this.sessionMap = arg0;
83
84 }
85
86
87 private Map requestMap;
88 public void setRequest(Map arg0) {
89 this.requestMap = arg0;
90
91 }
92
93
94
95
96 }
details.jsp
1
2 pageEncoding="UTF-8"%>
3
4
5
6
7
8
detail page9
10
11
12
13
14 ProductName:${productName }
15
16 ProductDesc:${productDesc }
17
18
19 ProductPrice:
20
21
22
23
24 ProductDesc1:${sessionScope.product.productName }
25
26
27
28
29 ProductDesc2:${requestScope.test.productName }
30
31
32
33
34
input.jsp
1
2 pageEncoding="UTF-8"%>
3
4
5
6
7
input page8
9
10
11
12 ProductName:
13
14
15 ProductDesc:
16
17
18 ProductPrice:
19
20
21
22
23
24
struts.xml
/p>
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
/details.jsp
③调用字段和方法,数组
>可以利用 OGNL 调用
任何一个 Java 类里的静态字段或方法. 被压入到 ValueStack 栈的对象上的公共字段和方法
>默认情况下, Struts2 不允许调用任意 Java 类静态方法, 需要重新设置 struts.ognl.allowStaticMethodAccess 标记变量的值为 true.
>调用静态字段或方法需要使用如下所示的语法:
-- @fullyQualifiedClassName@fieldName:
@java.util.Calendar@DECEMBER
- -@fullyQualifiedClassName@methodName(argumentList):
@app4.Util@now()
>调用一个实例字段或方法的语法, 其中 object 是 Object Stack 栈里的某个对象的引用:
-- .object.fieldName: [0].datePattern
-- .object.methodName(argumentList): [0].repeat(3, “Hello”);
例子:
1
2
3
4
5
6
7
8
9
10
>调用数组对象的属性
1
2
3 String[] names = new String[] {"aa","bb","cc"};
4 request.setAttribute("names", names);
5 %>
6
7 length:
8
9 names[2]:
>访问 List 类型的属性
有些属性将返回的类型是 java.util.List, 可以像读取任何其他属性那样读取它们. 这种 List 的各个元素是字符串, 以逗号分隔, 并且带方括号
可以使用下标访问 List 中指定的元素: colors[0]
可以通过调用其 size 方法或专用关键字 size 的方法查出给定List 的长度: colors.size 或 colors.size()
可以通过使用 isEmpty() 方法或专用关键字 isEmpty 来得知给定的 List 是不是空. colors.isEmpty 或 colors.isEmpty()
还可以使用 OGNL 表达式来创建 List, 创建一个 List 与声明一个 Java 数组是相同的: {“Red”, “Black”, “Green”}
>访问 Map 类型的属性
读取一个 Map 类型的属性将以如下所示的格式返回它所有的键值对:
若希望检索出某个 Map 的值, 需要使用如下格式: map[key]
可以使用 size 或 size() 得出某个给定的 Map 的键值对的个数
可以使用 isEmpty 或 isEmpty() 检查某给定 Map 是不是空.
1
2
3 Map letters = new HashMap();
4 letters.put("AA", "a");
5 letters.put("BB", "b");
6 letters.put("CC", "c");
7 request.setAttribute("letters", letters);
8 %>
9 letters.length:
10
11 AA:
使用 EL 访问值栈中对象的属性
也可以通过 JSP EL 来达到目的: ${fieldName}
原理: Struts2 将包装 HttpServletRequest 对象后的 org.apache.struts2.dispatcher.StrutsRequestWrapper 对象传到页面上, 而这个类重写了 getAttribute() 方法.