Struts2 04--- 值栈 ognl(S标签)
OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。中文名是对象图导航语言,我们通常叫做S标签。
那么,怎么在一个jsp页面中导S标签呢?只要在jsp页面的顶部写上这行代码:<%@ taglib uri="/struts-tags" prefix="s"%>,就可以将S标签导入页面中使用了。
Struts 2默认的表达式语言是OGNL。OGNL既可以取值,又可以作为页面标签使用。
首先简单介绍一下常用的OGNL页面标签:
form表单<s:form>
文本框:<s:textfield></s:textfield>
多行文本:<s:textarea></s:textarea>
密码框:<s:password></s:password>
下拉框:<s:select list="#{1:'请选择',2:'吃饭',3:'睡觉'}" name="select"></s:select>
下拉框:<s:combobox list="#{1:'请选择',2:'吃饭',3:'睡觉'}" name="下拉框" ></s:combobox>
单选框:<s:radio list="#{1:'打豆豆',2:'吃饭',3:'睡觉'}" name="单选框" value="1"></s:radio>
多选框:<s:checkboxlist list="#{1:'打豆豆',2:'吃饭',3:'睡觉'}" name="多选框" value="2"></s:checkboxlist>
</s:form>
标签在form表单里使用会自动换行,多选框也有另一种复杂一点的写法。但是ONGL不会作为常用的页面标签,因为我们一般写页面都有html的标签。
那么,既然它不会作为页面标签被我们常用,就来讲一下它的另一种用法,取值:它常用来获取值栈里面的值。
既然说到值栈,那么先简单介绍一下值栈。
值栈是struts2里面本身提供的一种存储机制,类似于域对象,值栈,可以存值和取值。存储在action对象中,每次访问action都会创建一个action对象,action对象里面有且只有一个值栈的对象。
值栈的存值形式分为两种,一种是保存在content中,结果是map集合。另一种是保存在root中,结果是list集合。我们常用的是root。值栈有一个最大的特点就是先进后出,存在于最顶端的值可称为栈顶元素,上一个元素和下一个元素之间的关系可称为压栈。
获取值栈对象:ActionContext actionContext = ActionContext.getContext();
ValueStack stack1 = actionContext.getValueStack();
package com.action; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.entity.Person; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; public class IndexAction extends ActionSupport { private String name; public String getName() { return name; } private Person p; public Person getP() { return p; } private List<Person> lp = new ArrayList<>(); public List<Person> getLp() { return lp; } @Override public String execute() throws Exception { // // 获取值栈对象 // ActionContext ac = ActionContext.getContext(); // // 值栈对象 存在于action对象中 (每一次访问action就会产生一个新的action对象) // ValueStack vs = ac.getValueStack(); // vs.push("PUSH开头"); // vs.set("name", "哈哈"); // vs.push("PUSH结尾"); // 单个变量 name = "哈哈"; // 单个对象 p = new Person(); p.setName("haha"); p.setAge(18); p.setSex("男"); // 单个集合 lp.add(new Person("asd", 1, "男")); lp.add(new Person("asda", 12, "男")); // 域对象 HttpServletRequest req = ServletActionContext.getRequest(); req.setAttribute("name", "我是域对象的值"); return SUCCESS; } }
<!-- 获取值值栈对象(Map) --> <s:property value="name"/> <!-- 获取值 (String) --> <s:property value="[2].top"/> --%> <!-- 获取值 获取单个 变量 --> <s:property value="name"/><br> <!-- 获取值 获取单个对象 --> <s:property value="p.name"/> <s:property value="p.age"/> <s:property value="p.sex"/><br> <!-- 获取值 集合 第一种方式--> <s:property value="lp[0].name"/> <s:property value="lp[1].name"/><br> <!-- 获取值 集合 第二种方式--> <s:iterator value="lp"> <s:property value="name"/> <s:property value="age"/> <s:property value="sex"/><br> </s:iterator> <!-- 获取值 集合 第三种方式--> <s:iterator value="lp" var="a"> <s:property value="#a.name"/> <s:property value="#a.age"/> <s:property value="#a.sex"/><br> </s:iterator> <!-- 获取值 集合 第四种方式--> <c:forEach items="${lp}" var="p"> ${p.name} ${p.age} ${p.sex} </c:forEach> <!-- 获取值 域对象 --> <s:property value="#request.name"/> <!-- s标签里放变量值 --> <!-- value所绑定的值是值栈里面name的值 --> <s:textfield value="%{name}"></s:textfield> <!--在页面上输出一个字符串--> <s:property value="'OGNL'"/>
<!--可以看见值栈里面所有的对象和值--> <s:debug></s:debug>