Java实战之01Struts2-05contextMAP、EL、OGNL
十五、contextMap
1、动作类的生命周期
明确:动作类是多例的,每次动作访问,动作类都会实例化。所以是线程安全的。与Struts1的区别是,struts1的动作类是单例的。
2、请求动作的数据存放
问题:
每次请求时,都会产生一些请求数据,这些数据存放到哪里去了?
明确:
在每次动作执行前,核心控制器StrutsPrepareAndExecuteFilter都会创建一个ActionContext和ValueStack对象。且每次动作访问都会创建。
这两个对象存储了整个动作访问期间用到的数据。并且把数据绑定到了线程局部变量(ThreadLocal)上了。所以是线程安全的。


3、contextMap:存储数据
Struts2的官方文档对contextMap的说明:

|
contextMap中存放的主要内容 |
||
|
Key |
Value |
说明 |
|
value stack (root) |
java.util.List |
没有root这个key。contextMap中它有key,但是我们不用。它是一个list。(com.opensymphony.xwork2.util.ValueStack.ValueStack是它的key)。 |
|
application |
java.util.Map<String,Object> |
ServletContext中的所有属性。 |
|
session |
java.util.Map<String,Object> |
HttpSession中的所有属性。 |
|
request |
java.util.Map<String,Object> |
ServletRequest中的所有属性。 |
|
parameters |
java.util.Map |
参数 |
|
attr |
java.util.Map |
把页面、请求、会话、应用范围内的所有属性放到一起。 |
注意:
除了value stack之外,全是map,而contextMap也是一个map。其实就是Map中又封装的Map。(很像dbutils中KeyedHandler封装数据的结构,只是封装数据的结构)
查看contextMap中的数据:
在页面上使用<s:debug/>



十六、contextMap中的数据操作
1、存数据:
需要熟悉ActionContext和valueStack的API。框架为我们存数据。
1.1、利用ActionContext存数据
public String demo1(){
//1.获取到ActionContext对象
ActionContext context = ActionContext.getContext();//从当前线程上获取
//2.往大map中存入数据
context.put("contextMap", "hello context map");
//3.往指定的小Map中存入数据(request,session,application)
//Map<String,Object> sessionMap = (Map<String, Object>) context.get("session");
//第一种方式:使用map操作
Map<String,Object> sessionMap = context.getSession();
sessionMap.put("sessionMap", "hello session map");
//第二种方式:使用原始ServletAPI存入数据
HttpSession session = ServletActionContext.getRequest().getSession();
session.setAttribute("sessionAttr","hello session attribute");
//4.往application的map中存入数据
//第一种方式:使用map操作
Map<String,Object> applicationMap = context.getApplication();
applicationMap.put("applicationMap", "hello application map");
//第二种方式:使用原始ServletAPI对象
ServletContext application = ServletActionContext.getServletContext();
application.setAttribute("applicationAttr", "hello application attribute");
return SUCCESS;
}
1.2、利用ValueStack存数据
a、如何获取ValueStack
/**
* 利用ValueStack存取数据操作
* 明确:
* 1、它本身是一个List结构,同时具备了栈的特点。
* 2、它里面只能存放对象,没有key,value的概念。
* @author zhy
*
*/
public class Demo2Action extends ActionSupport { private String name = "泰斯特"; public String demo2(){
//1.获取valueStack
//先获取ActionContext
ActionContext context = ActionContext.getContext();
context.put("contextMap", "hello context map");
//再使用ActionContext中的getValueStack方法获取
ValueStack vs = context.getValueStack();
/*
* 压栈操作
*/
Student s1 = new Student("test",18,"male");
vs.push(s1); Student s2 = new Student("test1",20,"female");
vs.push(s2); return SUCCESS;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }
b、ValueStack中的getRoot()方法:

c、CompoundRoot是什么:

d、栈操作:

2、取数据:用Struts2的标签(OGNL表达式)在JSP上
使用OGNL表达式来去,struts2的OGNL表达式必须写在struts2标签中。
2.1、使用s:property取数据
a、取contextMap中的数据,需使用#
<body>
<%--1.获取ValueStack中的数据 :
当我们使用s:property不指定value属性时,默认获取的是栈顶元素(对象)
注意:获取的是一个对象。
只有不使用value属性时,才获取的是对象。
剩余的情况全是:
根据属性名称获取属性值!!!!!!!!
--%>
<s:property/>
<hr/>
<%--2.获取指定属性的值
当s:property标签的value属性没有使用#号时,是从ValueStack中获取数据
把value的取值当做property name,从栈顶逐个元素往下寻找,找和value取值一样的属性,
找到了,把值获取回来。只要找到了,就不再继续寻找。 获取valueStack中的数据,不用写#号。并且直接写属性名称即可。
--%>
<s:property value="name"/>
<hr/>
<%--3.获取指定位置指定属性的值
[1]表示的不是属性名称出现的索引位置。
而是指的集合中元素(对象)的索引位置。 当我们使用[n].propertyname方式获取值时,它就是把栈中下标为n的元素看成是栈顶元素,逐个往下寻找。
--%>
<s:property value="[1].name"/>
<hr/>
<%--4.ValueStack中的findValue方法 --%>
<% ActionContext ac = ActionContext.getContext();
ValueStack vs = ac.getValueStack();
Object obj = vs.findValue("name");
Object obj1 = vs.findValue("[2].name");
out.print(obj);
out.print("<hr/>");
out.print(obj1);
out.print("<hr/>");
Object obj2 = vs.findValue("#contextMap");
out.print("aaaa:"+obj2);
%>
<%-- <s:property value="#contextMap"/> --%>
<s:debug/>
</body>

b、取contextMap里面ValueStack中对象的属性:直接写属性名
1 <tr>
<td><s:property value="name"/></td>
<td><s:property value="age"/></td>
<td><s:property value="gender"/></td>
</tr>

OGNL的使用总结:
1.取根中对象的属性,不使用#。
2.取contextMap中key的值,要使用#。
2.2、ValueStack的findValue方法(我们在Jsp上调用的都是findValue)

十七、Struts2对EL的改变
1、Struts2中使用EL的问题:
前提:
我们应该知道,如果我们没有往值栈(根)中放入数据的话,那么我们的动作类默认是在值栈的栈顶。



问题:
我们放到请求域中的属性,使用EL表达式取出来了。但是放到应用域中的属性,使用EL表达式没取出来。
2、关于EL问题的分析:
分析:
我们知道EL表达式是从四大域对象中依次查找属性。搜索范围是由小到大。page Scope————>request Scope————>sessionScope————>application Scope
但是通过测试发现,搜索完request范围后就没有继续搜索,而是返回了ValueStack中栈顶对象name属性的值。
3、Struts2中EL查找顺序改变总结:
EL表达式: page Scope————>request Scope————>sessionScope————>application Scope
OGNL表达式:page Scope————>request Scope————>valueStack(根中)————>contextMap————>sessionScope————>application Scope
4、OGNL的特殊说明:
public String demo3(){
//1.获取HttpServletRequest的对象
HttpServletRequest request = ServletActionContext.getRequest();
//2.往请求域中存放一个name
//request.setAttribute("name", "请求域中的name");
//3.获取HttpSession
HttpSession session = request.getSession();
session.setAttribute("name", "会话域中的name");
ActionContext context = ActionContext.getContext();
context.put("name", "大Map中的name");
return SUCCESS;
}
十八、OGNL配合通用标签的其他使用
1、iterator标签
/**
* iterator标签的使用
* @author zhy
*
*/
public class Demo4Action extends ActionSupport { private List<Student> students; public String demo4(){
//1.获取HttpServletRequest的对象
//HttpServletRequest request = ServletActionContext.getRequest();
//就相当于从数据库中获取学生列表
students = new ArrayList<Student>();
students.add(new Student("test1",18,"male"));
students.add(new Student("test2",21,"female"));
students.add(new Student("test3",22,"male"));
//2.把查询出来的学生列表存入请求域中
//request.setAttribute("students", students); return SUCCESS;
} public List<Student> getStudents() {
return students;
} public void setStudents(List<Student> students) {
this.students = students;
}
}
<s:iterator value="students">
<tr>
<td><s:property value="name"/></td>
<td><s:property value="age"/></td>
<td><s:property value="gender"/></td>
</tr>
</s:iterator>
2、Struts2中#,$,%符号的使用
2.1、#
a、取ActionContext中key时使用,例如<s:property value="#name" />
b、OGNL中创建Map对象时使用,例如:<s:radio list="#{'male':'男','female':'女'}" />
2.2、$
a、在JSP中使用EL表达式时使用,例如${name}
b、在xml配置文件中,编写OGNL表达式时使用,例如文件下载时,文件名编码。struts.xml——>${@java.net.URLEncoder.encode(filename,"UTF-8")}
2.3、%
在struts2中,有些标签的value属性取值就是一个OGNL表达式,例如<s:property value="OGNL Expression" />
还有一部分标签,value属性的取值就是普通字符串,例如<s:textfield value="username"/>,如果想把一个普通的字符串强制看成时OGNL,就需要使用%{}把字符串套起来。
例如<s:textfield value="%{username}"/>。当然在<s:property value="%{OGNL Expression}" />也可以使用,但不会这么用。
3、其他标签
3.1、if标签,elseif标签 else标签
<%--1、s:if s:elseif s:else
作用:
进行条件判断。
属性:
test里面的内容是一个逻辑运算,返回的结果应该是一个布尔类型值。
可以使用常量运算,还可以是OGNL表达式的逻辑 运算 test的取值可以是OGNL表达式,但是只能在ValueStack中取值 --%>
<%--没有经过动作类
ActionContext ac = ActionContext.getContext();
ac.put("name", "test");
--%>
<s:if test="name == null">
用户名没有了
</s:if>
<s:elseif test="#name == 'test'">
是一个测试用户
</s:elseif>
3.2、url和a标签
<%--2、s:url 和 s:a
s:url标签:
作用:是把指定路径存入contextMap中
属性:
action:直接写动作名称。不用再写${pageContext.request.contextPath}
namespace:指定动作所在的名称空间,如果该动作是在默认名称空间下可以不写
var:取值是一个普通字符串。把var的取值当做key,把action的取值当做value,存入contextMap中
s:param标签:
作用:是给s:url或者s:a添加请求参数
属性:
name:参数的名称
value:参数的值.它的取值是一个OGNL表达式.
s:a标签:
作用:和超链接标签是一样的。并且可以和s:url互换
--%>
<s:url action="action1" var="action1_url">
<s:param name="param1" value="'hello'"></s:param>
</s:url>
<a href="<s:property value="#action1_url"/>">let me see see</a> <br/>
<a href="${pageContext.request.contextPath}/action1.action">让我们看看</a>
<br/> <s:a action="action1" namespace="">
<s:param name="param1" value="'hello'"></s:param>
去action1 看看
</s:a>
3.3、date标签
<%--3、s:date --%>
<font color="red">我们想要的输出结果是:2016-05-30 或者是 2016年05月30日</font><br/>
<%--s:date标签:
作用:格式化输出日期
属性:
name:取值是一个OGNL表达式。指定的是要转换的日期对象
format:指定转换的格式
var:取值是一个普通的字符串。把var的值当做key,把转换好的日期当成value,存入contextMap中
--%>
<s:date name="birthday" format="yyyy-MM-dd" var="sbirthday"/>
<%--
DateFormat format = new SimpleDateFormat("yyyy年MM月dd日");
String date = format.format(birthday);
out.print(date);
--%> <s:property value="#sbirthday"/>
Java实战之01Struts2-05contextMAP、EL、OGNL的更多相关文章
- Java实战之04JavaWeb-04JSP、EL表达式、JSTL标签库
一.jsp部分 只要是与页面显示相关的都是重点 1.jsp的脚本 <%java代码%>:被翻译到service方法内部,局部变量,局部的功能 <%=表达式或变量%>:翻译成se ...
- Tomcat6环境JBPM4.4报错:java.lang.ClassNotFoundException: de.odysseus.el.util.SimpleResolver
Tomcat6环境JBPM4.4报错:java.lang.ClassNotFoundException: de.odysseus.el.util.SimpleResolver 报错信息:
- 「小程序JAVA实战」springboot的后台搭建(31)
转自:https://idig8.com/2018/08/29/xiaochengxujavashizhanspringbootdehoutaidajian31/ 根据下面的图,我们来建立下对应的sp ...
- JAVA基础之JSP与EL技术、JSTL技术
要牢记jsp四大作用域(pageContext域:当前jsp页面范围 request域:一次请求 session域:一次会话 application域:整个web应用)以及九大内置对 ...
- Java Web学习笔记之---EL和JSTL
Java Web学习笔记之---EL和JSTL (一)EL (1)EL作用 Expression Language(表达式语言),目的是代替JSP页面中复杂的代码 (2)EL表达式 ${变量名} ( ...
- Java实战:教你如何进行数据库分库分表
摘要:本文通过实际案例,说明如何按日期来对订单数据进行水平分库和分表,实现数据的分布式查询和操作. 本文分享自华为云社区<数据库分库分表Java实战经验总结 丨[绽放吧!数据库]>,作者: ...
- Java实战之01Struts2-04拦截器、上传下载、OGNL表达式
十二.Struts2中的拦截器 1.拦截器的重要性 Struts2中的很多功能都是由拦截器完成的.比如:servletConfig,staticParam,params,modelDriven等等. ...
- java实战之解析xml
在java中解析xml有现成的包提供方法,常用的有四类:Dom,JDom,Sax以及Dom4j.其中前者是java中自带的,后三者需要大家从开源诸如sourceforge这样的网站下载jar包,然后在 ...
- Java实战之03Spring-02Spring的核心之IoC
二.Spring的核心之IoC(Inversion of Control 控制反转) 1.IoC是什么? 回顾:连接池原理中的使用. 注意:我们在连接池原理中是使用构造函数注入的,当然还可以通过提供s ...
随机推荐
- 使用yum和iso镜像离线升级RedHat系统
创建一个用于挂载iso镜像的目录.由于这个目录不能在挂载时自动创建,所以需要以root身份先创建一个目录.命令: mkdir mount_dir 以root身份把iso镜像挂载到上一步创建的目录上.命 ...
- Spark系列(一)Spark1.0.0源码编译及安装
最近想对自己学的东西做些回顾,想到写博客是个不错的方式,方便他人也有利自己,刚开始写不足之处大家多担待. 编译前需要安装JDK1.6以上.scala.Maven.Ant.hadoop2.20 如下图( ...
- Apple LLVM 6.0 Warning: profile data may be out of date
I have no clue what this meant, so I googled the problem. I only ended up with some search results s ...
- php&mysql
更新语句 $query='update num set num='.$counter.'where id=1'; ....................这个查询失败 $query='upd ...
- javascript 如何判断一个对象的类型
<!DOCTYPE html> <html> <head> </head> <body> <script type="tex ...
- javascript的类和构造函数
在javascript中,类的实现是基于其原型继承机制的.如果两个实例都从同一个原型对象上继承了属性,我们就说它们是同一个类的实例.那么,如果两个对象继承自同一个原型,那基本上可以认为它们是由同一个构 ...
- 国外一些好用的UX/UI设计工具和资源分享
国外一些好用的UX/UI设计工具和资源分享 你今天使用的设计工具也许不再适合以后的网页和APP设计项目了.新的工具不断的推出市场,目标只有一个,让你的工作更快.更容易而且工作成效更好.今天分享的这些U ...
- Eclipse + Pydev 配置Python开发环境
之前有人问 Eclipse + Pydev 的环境配置问题,在此记录一下. 前提条件:需要安装 Eclipse .jdk.Python.这三个软件都可以在官网上下载. 假设上述软件已经安装好了,下面是 ...
- PHP中如何防止SQL注入
这是StackOverFlow上一个投票非常多的提问 How to prevent SQL injection in PHP? 我把问题和赞同最多的答题翻译了下来. 提问:如果用户的输入能直接插入到 ...
- springMVC项目引入jstl标签库若干问题的总结
中午,不知道动到项目的哪个地方了,之前在联系人列表页面用的好好的jstl标签库突然报错了:<%@taglib prefix="c" uri="http://java ...