2014-07-20 Java Web的学习(17)-----struts2(3)----OGNL&ValueStack
2015-04-10 16:49
741 查看
body, td { font-family: tahoma; font-size: 10pt; }
1.OGNL是什么? OGNL就是表达式引擎,所谓表达式引擎就是处理View层和Controller层之间流转数据.在视图层,既没有数据类型的概念,也没有数据结构的概念.一旦对外展现,都会最终转化为同一的字符串形式.而Controller(Java)中存在各种数据类型的数据.这时就需要一整套的数据匹配规则.这种规则就是表达式引擎的最初定义的概念.它的作用就是帮助我们完成这种规则化的表达式与Java对象的相互转化.因而它成为架起MVC各个模块之间数据沟通的桥梁.
在Java世界中,有许多优秀的表达式引擎.OGNL引擎在其内部实现机制和设计原理上存在许多的亮点,因而Struts2选择了OGNL框架作为它依赖的表达式引擎,而且在OGNL的基础上做了一定程度的扩展.
OGNL(Object Graph Navigation Language)是一个开源的表达式引擎.通过OGNL,我们能够通过表达式存取Java对象树中的任意属性和调用对象Java树的方法。 所以说,OGNL就是语义字符串与Java对象之间沟通的催化剂. 2.OGNL API
[align=left]/[/align] [align=left] The struts framework sets the OGNL context to be our ActionContext[/align] [align=left] and the value stack to be the OGNL root object.[/align] [align=left] (The value stack is a set of several objects[/align] [align=left] but to OGNL it appears to be a single object.)[/align] [align=left] [align=left] [/align] [align=left] */[/align] [align=left][b]public class Ognl {[/align] [align=left] /*[/align] [align=left] 通过传入OGNL表达式,在给定的上下文环境.从root对象中取值.[/align] [align=left] OGNL不是Struts独有的.解决的问题是:web层弱类型和Java强类型的之间的转换.表达式引擎.[/align] [align=left] [url=mailto:b>@param@param expression[/align] [align=left] [url=mailto:b>@param@param context ------- ActionContext[/align] [align=left] [url=mailto:b>@param@param root ------ ValueStack (虽然是数据结构是栈.A Stack that is implemented using a List)[/align] [align=left] [url=mailto:b>@return@return Object[/align] [align=left] /[/align] [align=left] public static Object getValue( String expression,Map context,Object root){[/align] [align=left] return null;[/align] [align=left] }[/align] [align=left] /[/b][/align] [align=left] 通过传入OGNL表达式,在给定的上下文环境.向root对象中写值.[/align] [align=left] [url=mailto:b>@param@param expression[/align] [align=left] [url=mailto:b>@param@param context[/align] [align=left] [url=mailto:b>@param@param root[/align] [align=left] [url=mailto:b>@return@return Object[/align] [align=left] /[/align] [align=left] public static void setValue(String expression,Map context,Object root){[/align] [align=left] }[/align] [align=left]}[/align] |
通过上述代码可以发现:OGNL引擎主要干两件事情.取值和存值.而这些操作都必须传入三个参数.以后无论OGNL如何完成复杂的操作,都会映射到这三个参数,通过调用底层引擎完成相关计算.从而完成OGNL功能需要三个要素: a.表达式(Expression),表达式会规定此次OGNL操作到底要干什么. b.Root对象.可以理解为OGNL的操作对象.也就是"对谁干",Root对象实际上就是一个Java对象,在struts2中相对应的就是实现ValueStack接口的类OgnlValueStack对象中CompoundRoot root对象.(CompoundRoot类是一个有Java List集合构建的栈的结构,存放一组对象.下面在详细说).The value stack is a set of several objects but to OGNL it appears to be a single object. c.上下文环境(OgnlContext).有了表达式和Root对象.就已经可以使用OGNL的基本功能.不过,事实上在OGNL内部,所有的操作都会在一个特定的数据环境中运行,这个数据环境就是OGNL的上下文环境(Context)。说的明白一些,就是这个上下文环境规定OGNL的操作"在哪里干",OGNL的上下文环境就是Map结构.之前所提及的Root对象,也会被添加上下文环境中,并且被作为一个特殊的变量进行处理.在Struts2中就是ActionContext类实现的. |
public class ActionContext implements Serializable { //通过ThreadLocal设计模式,实现ActionContext一次访问中的数据共享.线程安全 static ThreadLocal<ActionContext> actionContext = new ThreadLocal<ActionContext>(); / Constant for the {@link com.opensymphony.xwork2.util.ValueStack OGNL value stack}. / public static final String VALUE_STACK = ValueStack.VALUE_STACK; // [b]ActionContext中存储数据的上下文环境,ValueStack就存储其中,也有个名字叫做OgnlContext private Map<String, Object> context; /[/b] Stores a value in the current ActionContext. The value can be looked up using the key. @param key the key of the value. @param value the value to be stored. / public void put(String key, Object value) { context.put(key, value); } /* Returns a value that is stored in the current ActionContext by doing a lookup using the value's key. @param key the key used to find the value. @return the value that was found using the key or <tt>null</tt> if the key was not found. / public Object get(String key) { return context.get(key); } / Sets the OGNL value stack. 设置ValueStack @param stack the OGNL value stack. / public void setValueStack(ValueStack stack) { put(VALUE_STACK, stack); } / Gets the OGNL value stack. 获取ValueStack @return the OGNL value stack. / public ValueStack getValueStack() { return (ValueStack) get(VALUE_STACK); } } |
ValueStatck是针对OGNL计算的扩展,实际上就是针对OGNL三要素中Root对象所进行的扩展.使得在Struts2在使用ValueStack进行OGNL、计算时,可以将一组对象都视为Root对象. |
OgnlValueStack类的源代码: |
public class OgnlValueStack implements Serializable, ValueStack, ClearableValueStack, MemberAccessValueStack { //使用装饰模式,将根元素(栈结构)封装在ValueStack对象内容. //从外界来看,所有的操作就像针对单一对象的操作.实际在内部,是List形成的栈结构. CompoundRoot root; //OnglContext对象 [align=left] transient Map<String, Object> context; [/align] //构造函数,这里讲制定OGNL计算所需的参数 protected OgnlValueStack(ValueStack vs, XWorkConverter xworkConverter, CompoundRootAccessor accessor, boolean allowStaticAccess) { //调用setRoot方法完成初始化 setRoot(xworkConverter, accessor, new CompoundRoot(vs.getRoot()), allowStaticAccess); } //真正的OgnlValueStack的初始化过程. protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor, CompoundRoot compoundRoot, boolean allowStaticMethodAccess) { //根对象是一个CompoundRoot类型的栈结构 this.root = compoundRoot; this.securityMemberAccess = new SecurityMemberAccess(allowStaticMethodAccess); //创建OGNL的上下文 this.context = Ognl.createDefaultContext(this.root, accessor, new OgnlTypeConverterWrapper(xworkConverter), securityMemberAccess); //设置OGNL上下文的其他相关参数 context.put(VALUE_STACK, this); Ognl.setClassResolver(context, accessor); ((OgnlContext) context).setTraceEvaluations(false); ((OgnlContext) context).setKeepLastEvaluation(false); } } |
OgnlValueStack使用了一个典型的装饰模式,真正的其内部起到核心作用的是一个叫做CompoundRoot root的数据结构,可以存储多个对象(栈结构).ValueStack是一个被设计成"栈"的数据结构.并且还是一个具备表达式引擎计算能力的数据结构.OGNL与Stack的结合. |
/* A Stack that is implemented using a List. @author plightbo @version $Revision: 894090 $ */ public class CompoundRoot extends ArrayList { public CompoundRoot() { } public CompoundRoot(List list) { super(list); } public CompoundRoot cutStack(int index) { return new CompoundRoot(subList(index, size())); } public Object peek() { return get(0); } public Object pop() { return remove(0); } public void push(Object o) { add(0, o); } } |
相关文章推荐
- 【JavaWeb-17】国际化、自定义拦截器、struts2文件上传与下载、OGNL、contextMap
- JavaWeb开发知识总结(六)-(struts2_ognl_valuestack_interceptor)
- JAVAWEB开发之Struts2详解(四)——ognl与valueStack(重点)、Struts常用标签、防止表单重复提交、Struts2中内置json插件
- Java_WEB开发_struts2学习的总结_Iterate标签遍历
- Struts2中OGNL,valueStack,stackContext的学习
- JAVA_WEB Struts2学习:struts2自定义拦截器
- [原]java专业程序代写(qq:928900200),学习笔记之基础入门<Struts2_实战演练(上)>(三十八)
- JAVA_WEB Struts2学习:使用验证框架进行校验JSP页面元素 反编译工具的配置 Strtuts2 国际化学习
- Struts2中OGNL,valueStack,stackContext的学习
- JAVA_WEB Struts2学习:Struts2框架搭建图及源代码
- JAVA_WEB Struts2学习:struts2自定义类型转换类
- JAVA_WEB Struts2学习:Struts2标签学习2
- java web开发学习-10 netbeans如何导入struts2插件
- Struts2中OGNL,valueStack,stackContext的学习
- JAVA_WEB Struts2学习:Struts2解耦、耦合方式获取request、session、aplication对象
- Java_WEB开发_struts2学习的总结
- Struts2 ValueStack & ActionContext & OGNL 关系
- 【JavaWeb_struts2学习杂记】struts2的使用配置
- Struts2中OGNL,valueStack,stackContext的学习
- java web从零单排第十三期《struts2》OGNL上下文