目录
OGNL表达式与struts2结合原理
valuestack
队列:先进先出
栈:先进后出
list集合制作栈结构容器
push 压栈
list.add(0,xxx) 从前面增减
pop弹栈
list.remove(0) 把零号元素移除 并返回0号数据
查看接口valuestack的实现类OgnlValueStack
public class OgnlValueStack implements Serializable, ValueStack, ClearableValueStack, MemberAccessValueStack {
CompoundRoot root;
transient Map<String, Object> context;
}
public class CompoundRoot extends ArrayList {
public CompoundRoot() {
}
public CompoundRoot(List list) {
super(list);
}
public CompoundRoot cutStack(int index) {
return new CompoundRoot(this.subList(index, this.size()));
}
public Object peek() {
return this.get(0);
}
public Object pop() {
return this.remove(0);
}
public void push(Object o) {
this.add(0, o);
}
}
可以看到compoundRoot是根据list来实现的。
在取struts中的root栈属性的时候会遵循先进后出的原理。
写一个action
public class Demo12Action extends ActionSupport {
@Override
public String execute() throws Exception {
System.out.println("Demo12Action");
return SUCCESS;
}
}
配置struts.xml
<action name="Demo12Action" class="cn.ycsj.struts.Demo11Action" method="execute">
<result name="success" >
/showvs.jsp
</result>
</action>
showvs.jsp调试
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<s:debug></s:debug>
</body>
</html>
值栈
root栈
默认情况下栈中放置的是当前的action对象
context
stackcontext中放置的actioncontext (数据中心)
2.ognl表达式和struts2结合的体现
2.1参数接收中的体现
属性驱动
对象驱动
模型驱动
实现modeldrive接口,在params拦截器前执行,将接收到的参数压入栈顶。
如何获得值栈
ValueStack valueStack = ActionContext.getContext().getValueStack();
valueStack.push(xxx);
2.2配置文件中的体现
案例在重定向action中传递参数
Demo13Action
package cn.ycsj.struts;
import com.opensymphony.xwork2.ActionSupport;
public class Demo13Action extends ActionSupport {
private String name;
@Override
public String execute() throws Exception {
name = "jim" ;//假设是从数据库中取出来的
System.out.println("Demo13Action");
return SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
struts.xml
<action name="Demo13Action" class="cn.ycsj.struts.Demo13Action" method="execute">
<result name="success" type="redirectAction">
<param name="actionName" >Demo12Action</param>
<param name="namespace">/</param>
<!--如果添加的参数struts看不懂,就会做我参数跟在附加重定向请求后面
如果参数是动态的可以使用${}包裹ognl表达式动态取值-->
<param name="name">${name}</param>
</result>
浏览器访问http://localhost:8080/HibernateTest/Demo13Action.action
重定向到http://localhost:8080/HibernateTest/Demo12Action.action?name=jim
2.3struts2标签中的体现
示例写一个action 并模拟一个从数据库查出的数据访日context数据中心
public class Demo14Action extends ActionSupport { @Override public String execute() throws Exception { User user1 = new User("zhangsan",18); User user2 = new User("lisi",15); User user3 = new User("wangwu",12); List<User> userList = new ArrayList<>(); userList.add(user1); userList.add(user2); userList.add(user3); ActionContext.getContext().put("list",userList);
//ActionContext.getContext().getValueStack().push(userList); //放入栈
return SUCCESS; } }
struts.xml配置文件
<action name="Demo14Action" class="cn.ycsj.struts.Demo14Action" method="execute"> <result name="success" > /view.jsp </result> </action>
jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<table>
<tr>
<td>用户名</td>
<td>年纪</td>
</tr>
<!-- 方法1使用el表达式取 从request域中获取的 先从request对象中获取 然后从值栈中获取 root 和actioncontext 需要导入jstl的jar包 -->
<c:forEach items="${list}" var="user">
<tr>
<td>${user.name}</td>
<td>${user.age}</td>
</tr>
</c:forEach>
<!--方式2 使用struts标签取 从ognl表达式方式 从list中遍历 从取出来的数据压入值栈
-->
<s:iterator value="#list">
<tr>
<td><s:property value="name"/></td>
<td><s:property value="age"/></td>
</tr>
</s:iterator>
<!--方式3 使用var 将取出来的数据放入actioncontext中 -->
<s:iterator value="#list" var="user">
<tr>
<td><s:property value="#user.name"/></td>
<td><s:property value="#user.age"/></td>
</tr>
</s:iterator>
</table>
</body>
</html>