contextMap
来源:互联网 发布:医学动画视频知乎 编辑:程序博客网 时间:2024/06/03 07:26
Struts2的官方文档对contextMap的说明:
说明:
动作类的生命周期
明确:动作类是多例的,每次动作访问,动作类都会实例化。所以是线程安全的。与Struts1的区别是,struts1的动作类是单例的。
请求动作的数据存放
在每次动作执行前,核心控制器StrutsPrepareAndExecuteFilter都会创建一个ActionContext和ValueStack对象。且每次动作访问都会创建。
这两个对象存储了整个动作访问期间用到的数据。并且把数据绑定到了线程局部变量(ThreadLocal)上了。所以是线程安全的。
个人理解:ContextMap是绑定到了线程上面了,成为了局部变量,上图中他包含的对象的引用就是httpServletRequet,Seesion等。这个里面的session,request,application等都各自只有一份,我们可以通过各种不同的方式拿到对象的引用
contextMap:存储数据
contextMap是有两个部分组成的,一个是ActionContext,它是一个map;一个是valueStack,它是一个栈。这两部分就是用来存取数据用的
1、利用ActionContext存数据;
ActionContext的获取需要调用getContext()从当前线程中获取
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 Demo1Action extends ActionSupport { public String execute(){ //1得到ActionContext对象,这个时候最大的map对象 ActionContext context = ActionContext.getContext(); //向其中添加数据 context.put("contextMap", "hello,world!"); System.out.println(context.hashCode()); ActionContext context2 = ServletActionContext.getContext(); System.out.println(context2.hashCode()); //往session中存取数据 //1.使用Actioncontext获取sessionMap Map<String, Object> sessionMap = context.getSession(); sessionMap.put("name", "yanglin"); //2.得到session对象来存取 HttpSession session = ServletActionContext.getRequest().getSession(); session.setAttribute("age",23); //往ServletContext域中存取数据 //方式一: Map<String, Object> applicationMap = context.getApplication(); applicationMap.put("domain", "my"); //方式二: ServletContext servletContext = ServletActionContext.getServletContext(); servletContext.setAttribute("way", "way"); return SUCCESS; }}
2、利用ValueStack存数据:
valuestack的获取方式有如下几种:
获取ValueStack对象的引用 //第一种方式:获取HttpServletRequest对象,通过对象的getAttribute方法,从域中取 //1.获取request对象 HttpServletRequest request = ServletActionContext.getRequest(); //2.根据key获取ValueStack对象的引用 ValueStack vs1 = (ValueStack)request.getAttribute("struts.valueStack"); System.out.println(vs1.hashCode()); //第二种方式:先获取ActionContext对象,再取出requestMap,然后通过map的get方法获取 //1.获取ActionContext对象 ActionContext context = ActionContext.getContext(); //2.获取requestMap Map<String,Object> requestAttribute = (Map<String,Object>)context.get("request"); //3.根据key获取对象的引用 ValueStack vs2 = (ValueStack)requestAttribute.get("struts.valueStack"); System.out.println(vs2.hashCode()); //第三种方式:使用ActionContext对象的方法,直接获取ValueStack对象的引用 ValueStack vs3 = context.getValueStack(); System.out.println(vs3.hashCode());
ValueStack中有一个getRoot()方法:
CompoundRoot是一个具有栈功能的继承了arraylist的类
栈的操作:
valueStack.push(new Student("zeroyoung",23));/*** 栈的其他方法:* setValue(String expr, Object value);* String expr:它是一个OGNL表达式* Object value:我们要操作的数据* 把数据存到哪里去?* 看expr是否使用了#* 如果使用了#,操作的就是ContextMap中* 如果没使用#,操作的就是ValueStack*/valueStack.setValue("#names", "fuck");//把数据放到ContextMap中。 key是name valeu=张三valueStack.setValue("name", "张三");//把ValueStack中第一个name属性的值换成李四。如果没有一个name属性的对应的setName方法,会报错。/**set(String key, Object o);* String key : Map的key* Object o : map的value* 如果栈顶是一个Map元素,直接把key作为map的key,把Object作为map的value存入。执行的是替换的操作存入的是栈顶。* 如果栈顶不是一个Map元素,创建一个Map对象,把key作为map的key,把Object作为map的value,压入栈顶。执行的是进栈的操作 */valueStack.set("s1", new Student("王五",18));valueStack.push(new Student("test",23));valueStack.set("s2", new Student("aaa",28));
3、取数据:用Struts2的标签(OGNL表达式)在JSP上用的最多
使用OGNL表达式来去,struts2的OGNL表达式必须写在struts2标签中。
<%@ taglib uri="/struts-tags" prefix="s" %>
- 使用s:property取数据
a、取contextMap中的数据,需使用#
<%-- 使用 s:property来获取ActionContext中的数据 value属性的取值是一个OGNL表达式--%> <br/>---------获取大Map中的数据-------------<br/> <s:property value="#contextMap"/> <hr/> <br/>---------获取小Map中的数据,session等中的数据-------------<br/> <%-- 以为小map在大map中,所有使用#大Map的key.小Map的key --%> <s:property value="#session.name" /><br/> <s:property value="#session.age" /><br/> <s:property value="#application.way" />
b、取contextMap里面ValueStack中对象的属性:直接写属性名
如果遇有对象属性重名,可以通过OGNL表达式,选择查找的起始位置
<%--使用s:property标签,获取ValueStack中的元素。 value属性的取值是一个OGNL表达式。它只能获取元素中的属性。 注意: 取ValueStack中的对象属性时,不使用#。 它是从栈顶逐个对象查找指定的属性名称。只要找到了,就不再继续查找。 --%> <s:property value="name"/><br/> <s:property value="s2.name"/><br/> <hr/> <%--当s:property什么都不写: 默认取栈顶元素 --%> <s:property /> <%--获取ValueStack中指定位置的属性 : 使用的是[索引].属性名称。这个功能的实现是使用切片的方式, [2].name意思是去掉栈顶的两个元素之后然后再在valueStack的 Property Name中一个一个往下寻找寻找key --%> 0-name <s:property value="[0].name" /><br/> 1-name <s:property value="[1].name" /><br/> 2-name <s:property value="[2].name" /><br/> 3-name <s:property value="[3].name" /><br/> 4-name <s:property value="[4].name" /><br/>
特殊说明:当s:property不给定value属性时,默认取栈顶对象。
OGNL的使用总结:
- 取根(valueStack)中对象的属性,不使用#。
- 取contextMap中key的值,要使用#。
- contextMap
- ContextMap详解
- ContextMap详解
- ContextMap详解
- 【Struts】ContextMap详解
- struts2的contextmap和valueStack
- struts2的contextmap和valueStack
- Struts2的valueStack与actionContext(contextMap)的取值
- 【JavaWeb-17】国际化、自定义拦截器、struts2文件上传与下载、OGNL、contextMap
- struts里面值栈valuestack和上下文contextMap的理解和使用
- Java中的IO
- [阅读笔记]Modern C++ Programming with Test-Driven Develpment chp2
- H264编码原理以及I帧B帧P帧
- Java中的集合
- json_decode 不转义中文汉字的方法
- contextMap
- 自主学习
- Java中的异常
- sqlserver数据库的JDBC
- mobiscroll 日期控件
- Java字节码操作类库汇总
- 一道Java笔试题:静态语句块、构造语句块和构造函数的执行顺序
- srping&mybatis
- Java多线程