好记性不如赖笔头…………
ValueStack与ActionContext是由Struts2的拦截器创建的,ValueStack是一个栈结构的数据,内部是由list组成,而ActionContext是一个Map,里面可以嵌套多层Map
获取ValueStack的值
1.创建TestBean实体类,具体代码如下:
package com.ckinghan.bean;
import java.io.Serializable;
public class TestBean implements Serializable {
private String nature;
private int num;
public String getNature() {
return nature;
}
public void setNature(String nature) {
this.nature = nature;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public TestBean() {
super();
}
public TestBean(String nature, int num) {
super();
this.nature = nature;
this.num = num;
}
}
2.创建ValueStack1Action动作类,继承ActionSupport,具体代码如下:
package com.ckinghan.web.action;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.ckinghan.bean.TestBean;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class ValueStack1Action extends ActionSupport {
private TestBean testBean = new TestBean("testBean",100);
public TestBean getTestBean() {
return testBean;
}
public void setTestBean(TestBean testBean) {
this.testBean = testBean;
}
/**
* 通过三种方法获取ValueStack对象,可以发现他们是同一个对象
* @return
*/
public String getValueStack1(){
//获取ActionContext
ActionContext actionContext = ActionContext.getContext();
//获取ValueStack栈的方法一
ValueStack valueStack1 = actionContext.getValueStack();
//获取ValueStack栈的方法二
Map<String, Object> requestMap = (Map<String, Object>) actionContext.get("request");
ValueStack valueStack2 = (ValueStack) requestMap.get("struts.valueStack");
//获取ValueStack栈的方法三
HttpServletRequest request = ServletActionContext.getRequest();
ValueStack valueStack3 = (ValueStack) request.getAttribute("struts.valueStack");
//将通过三种方法获取到的ValueStack栈对象的hashCode()放入到actionContext中,在页面显示
actionContext.put("valueStack1", "使用方法一获取的valueStack的对象为:"+valueStack1.hashCode());
actionContext.put("valueStack2", "使用方法二获取的valueStack的对象为:"+valueStack2.hashCode());
actionContext.put("valueStack3", "使用方法三获取的valueStack的对象为:"+valueStack3.hashCode());
/*
* 通过ValueStack对象存储数据到actionContext中,ValueStack提供了一个方法:setValue
* setValue(String expr,Object obj)参数说明:
* String expr:表达式名称
* Object obj:在操作存储的数据
* expr详细说明:
* 如果expr的命名前加了#号,则是将值存储到了contextMap中
* 如果expr的命名前没有加#号(如:#class),则是将值存储到了ValueStack中。
* 如果ValueStack已经存在了class的属性,则会将ValueStack顶端的class属性值替换掉。
* 如果ValueStack不存在class的属性,则会直接报错,因为它在存储值时,是使用了反射的setClass方法来存储的,而没有这个方法,就会报错
*/
//将bean压进栈中(将Bean存储到ValueStack栈中)
valueStack1.push(testBean);
//将值存储到ValueStack中,如果不存在nature的属性,会报错,如果存在nature的属性,会替换最顶端的nature属性数据
valueStack1.setValue("nature", "将nature存储到ValueStack中");
//将值存储到contextMap大Map中,只须要在属性前面加#号即可
valueStack1.setValue("#nature", "将nature存储到contextMap中");
//将值存储到contextMap中的Session中
valueStack1.setValue("#session.nature", "测试将nature的值存储到ContextMap中的session中");
/*
* ValueStack的对象提供了一个set方法,用存储数据到ValueStack,详情如下:
* set(String key, Object o)
* String key : Map 的key
* Object o : Map的value
* 如果ValueStack的栈顶是一个Map,则key替换Map的key,value替换Map的value。注意:这里说的是栈顶是一个Map
* 如果ValueStack的栈顶不是一个Map,则创建一个新的Map,存储 到ValueStack的栈顶。
*/
valueStack1.set("nature_ok", "这是做为一个Map存储进入ValueStack中的,这里可以存储实体类及其它的数据");
return SUCCESS;
}
}
3.配置Struts.xml文件,具体内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true"/>
<package name="getContextMap" extends="struts-default">
<action name="getValueStack1" class="com.ckinghan.web.action.ValueStack1Action" method="getValueStack1">
<result>/getValueStack1.jsp</result>
</action>
</package>
</struts>
4.创建getValueStack1.jsp,具体代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>OGNL-获取ValueStack中的数据-数据类型为list</title>
</head>
<body>
<h1>查看Struts2-OGNL标签中的ActionContext(ValueStack)内容</h1>
<hr/>
<h1>通过三种方法获取的ValueStack对象为:</h1>
<s:property value="#valueStack1"/><br>
<s:property value="#valueStack2"/><br>
<s:property value="#valueStack3"/><br>
<hr/>
<h1>获取ValueStack栈中的数据,它的属性名称前不须要任何符号即可取值</h1>
<s:property value="nature"/><br/>
<s:property value="#nature"/><br/>
<s:property value="#session.nature"/><br/>
<s:property value="nature_ok"/>
<hr/>
<h1>
ValueStack的取值顺序是从栈的顶端一直到栈的底部取的,当找到要取出的属性后,就会停止查找的动作,
直接将值返回,如果想查找指定索引的值,取值方式为[索引].属性名
</h1>
默认取值是ValueStack的顶端的元素:<s:property /><br/>
<s:property value="#application.applicationMap"/>
</body>
</html>
启动项目,访问结果如下
获取ActionContext(contextMap)的值
1、创建ContextMap1Action动作类,并继承actionSupport,具体代码如下:
package com.ckinghan.web.action;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class ContextMap1Action extends ActionSupport {
/**
* ognl标签内部主要是contextMap,它是一个大MAP,
* @return
*/
public String getContextMap1(){
//获取ActionContext,从当前线程中获取局部变量的引用,可以保证它是线程安全的。
ActionContext actionContext = ActionContext.getContext();
//往大Map中保存一个新的变量,可以在<s:property value="#actionContextMap">标签中获取
actionContext.put("actionContextMap", "actionContextMap");
//往Session中添加数据一,它是大Map中的一个小Map
Map<String, Object> sessionMap = actionContext.getSession();
sessionMap.put("sessionMap", "sessionMap");
//Session中添加数据二,它是大Map中的一个小Map
HttpSession session = ServletActionContext.getRequest().getSession();
session.setAttribute("session", "session");
//Application添加数据一,它是大Map中的一个小Map
Map<String, Object> applicationMap = actionContext.getApplication();
applicationMap.put("applicationMap", "applicationMap");
//Application添加数据二,它是大Map中的一个小Map
ServletContext application = ServletActionContext.getServletContext();
application.setAttribute("application1", "application");
return SUCCESS;
}
}
2.在struts.xml配置文件的package标签内添加 以下内容
<action name="getContextMap1" class="com.ckinghan.web.action.ContextMap1Action" method="getContextMap1">
<result>/getContextMap1.jsp</result>
</action>
3.添加getContextMap1.jsp文件,具体代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ActionContext的取值</title>
</head>
<body>
<h1>查看Struts2-OGNL标签中的ActionContext(contextMap)内容</h1>
<s:debug/>
<hr/>
<h1>获取大Map中的数据(MAP的第一层数据,里面包括了session/application等Struts2已经提供的数据),获取数据时,以#号开头,会去contextMap中去查找</h1>
<s:property value="#actionContextMap"/>
<hr/>
<h1>获取Session中的sessionMap数据,因session的数据处于大MAP的第一层,所以它内部的数据处理于第二层,获取方式为:#session.key</h1>
<s:property value="#session.sessionMap"/><br/>
<s:property value="#session.session"/>
<hr/>
<h1>获取Application(ServletContext)数据,application的数据处于大MAP的第二层,所以获取方式为:#application.key</h1>
<s:property value="#application.application1"/><br/>
<s:property value="#application.applicationMap"/>
</body>
</html>
启动项目,访问结果如下:
注意:之所以通过不同的方式获取的valueStack都是同一个,是因为他们绑定了当前线程。