1. ONGL入门
1.1 引入struts-tags标签库
<%@ taglib uri="/struts-tags" prefix="s"%>
1.2 使用ONGL表达式
- ONGL表达式能执行java代码丶能获取值栈中的值等
<s:property value="1+1"/>
2. 值栈ValueStack
2.1 概述
- 值栈分为root区域和context区域
- root区域存储的是Action的字段属性丶ValueStack的push()和set()存储的数据等
- context存储的是pageContext丶request丶session丶application作用域中setAttribute存储的数据,还存储了attr(从pageContext~application逐一查找)丶parameters(请求参数)
2.2 值栈读写值
- root区域数据不用#开头,context区域数据要#开头
- 读取请求域数据时,如果找不到数据会从值栈中查找,所以EL表达式可以访问值栈的数据
//Action中定义的字段属性自动会存放进值栈中的root区域中
private String data;
//需要getter方法才可以使用ONGL表达式读取
public String getData() {
return data;
}
public String test1(){
data="值栈root区域中的数据";
//获取值栈对象
ValueStack valueStack=ActionContext.getContext().getValueStack();
Student student = new Student("张三",1);
Grade grade=new Grade("初三(2)班");
//把对象中的每个属性分别放进值栈的root区域中
valueStack.push(student);
//把整个对象放进值栈的root区域中
valueStack.set("student", student);
//在Request作用域中存值(也会存放在值栈的context区域中)
ServletActionContext.getRequest().setAttribute("grade", grade);
return "test1";
}
<!-- 可以直接根据Action中定义的字段属性名字获取值 -->
Action中定义的字段属性:<s:property value="data"/><br>
<!-- ValueStack的push方法时把对象的每个属性都分别放进值栈中,所以通过对象属性名即可取值,不用加对象名前缀 -->
ValueStack的push方法:<s:property value="name"/><s:property value="sex"/><br>
<!-- ValueStack的set方法设置的是键值对,所以需要对象名前缀 -->
ValueStack的set方法:<s:property value="student.name"/><s:property value="student.sex"/><br>
<!-- 访问值栈的context区域(pageContext、request丶session丶application丶parameters丶attr等)都要以#开头 -->
访问请求域的数据:<s:property value="#request.grade.name"/><br/>
EL表达式获取值栈数据:${student.name}
<!-- 显示值栈的调试信息 -->
<s:debug></s:debug>
3. 常用的ONGL表达式
ValueStack valueStack=ActionContext.getContext().getValueStack();
List<Integer> numList=new ArrayList<Integer>();
numList.add(1);
numList.add(2);
numList.add(3);
List<Grade> gradeList=new ArrayList<Grade>();
Grade g1=new Grade("高一(1)班");
Grade g2=new Grade("高一(2)班");
Grade g3=new Grade("高一(3)班");
gradeList.add(g1);
gradeList.add(g2);
gradeList.add(g3);
Map<String,Grade> gradeMap=new HashMap<String,Grade>();
gradeMap.put("g1", g1);
gradeMap.put("g2", g2);
gradeMap.put("g3", g3);
valueStack.set("numList",numList);
valueStack.set("gradeList",gradeList);
valueStack.set("gradeMap",gradeMap);
<!-- 条件判断 -->
<s:if test="numList.size()>2">
<hr/><hr/><hr/>
</s:if>
<s:elseif test="numList.size()>1">
<hr/><hr/>
</s:elseif>
<s:else>
<hr/>
</s:else>
<!-- 遍历普通集合 -->
<!-- status表示遍历过程中当前的位置信息 -->
<s:iterator value="numList" status="s">
<!-- s.index表示当前下标,以0开始 -->
<!-- s:property可以不填value值,默认遍历输出当前的值 -->
第${s.index+1}个数字:<s:property/><br/>
</s:iterator>
<!-- 通过下标获取List集合中对象的属性 -->
<s:property value="gradeList[1].name"/><br/>
<!-- var表示遍历过程当前项的别名 -->
<s:iterator var="grade" value="gradeList">
<!-- 用了别名访问对象属性需要加# -->
<s:property value="#grade.name"/><br/>
</s:iterator>
<!-- 通过键名获取Map集合的值,键名要用单引号括住 -->
<s:property value="gradeMap['g2'].name"/>
<br/>
<!-- 遍历Map集合 -->
<s:iterator value="gradeMap">
<!-- key表示当前遍历的键 -->
<s:property value="key"/>
<!-- key表示当前遍历的值,如果值时对象,可以直接调用其属性 -->
<s:property value="value.name"/><br/>
</s:iterator>
<!-- 遍历Map集合方式2(了解即可) -->
<s:iterator var="entry" value="gradeMap">
<s:property value="#entry.key"/><br/>
<s:property value="#entry.value.name"/><br/>
</s:iterator>