博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ongl 与 ValueStack ActionContext
阅读量:2454 次
发布时间:2019-05-10

本文共 3405 字,大约阅读时间需要 11 分钟。

转自:

Ognl.setValue(String expr, Object obj, Object value) 与 Ognl.getValue(String expr, Object obj)执行规则:

上面两个函数都不支持以“#”开头的ognl表达式。

Ognl.getValue(“a.b.myFunction()”, obj)为例,执行规则如下:

1. 如果obj实现map接口:obj.get("a")
2. 如果obj不实现map接口:obj.getA()/isA()

返回的对象又根据上面的规则来执行get("b")或getB()/isB(),接着返回的对象执行myFunction()函数。

 

对应的,Ognl.setValue(“a.b.myFunction().d”, obj, value)的执行规则开始时与上面一样,到最后一步时:

1. 如果当前对象实现map接口则执行 put("d",value)
2. 如果当前对象不实现map接口则执行 setD(value)

正规的代码一个类不应该既有getA()方法又有isA()方法,所以我就没测试若这两个方法都有会执行哪个了。

 

Ognl.getValue(String expr, Map map, Object obj)执行规则:

如果expr以“#”开头,执行Ognl.getValue(expr.substring(1), map),否则执行Ognl.getValue(expr, obj)。

 

关于异常:
1.如果在执行函数之前没有获得对象,譬如说obj.getA()返回的是null,null再执行getB()/isB()就会产生空指针异常。
2.如果得到的对象没有下一个要执行的函数,譬如说obj.getA()返回一个对象,但这个对象没有getB()/isB()函数,也产生异常。
Ognl把上面两种异常都进行了封装,转抛出它定义的Ognl异常。

——————————————————————————————————————————————————

获得当前ActionContext:
ActionContext ctx = ActionContext.getContext();
ActionContext里面包含了一个Map结构,称为context。

 

获得ValueStack:
ValueStack stack = ActionContext.getContext().getValueStack();
ValueStack里面包含了一个List结构,称为root。

 

获得Root:
CompoundRoot root = ActionContext.getContext().getValueStack().getRoot();
CompoundRoot的数据结构是一个List,作为一个栈来使用。

 

获得Context:
Map<String,Object> context = ActionContext.getContext().getContextMap();
Map<String,Object> context = ActionContext.getContext().getValueStack().getContext();

——————————————————————————————————————————————————

根据ognl取出对象:
Object obj =  stack.findValue(String expr);
expr是指定对象的ongl表达式。找不到返回null,不抛异常。

根据ognl设置对象:
stack.setValue(String expr, Object value);
expr是被设置对象的ongl表达式。找不到等于什么都没干,不抛异常。
value是设置为该对象。

Root操作:
Object obj = stack.pop();   取出Root栈顶对象并把它从Root移除。
Object obj = stack.peek();  取出Root栈顶对象不把它从Root移除。
stack.push(Object o);       把对象o放入Root栈顶。

Context操作:
actionctx.put(String key, Object value); 把一个对象放入Context里。
key是放入Context时对象的key,value是放入Context的对象。

——————————————————————————————————————————————————
ValueStack的findValue(String expr)与setValue(String expr, Object value)的查找顺序:
如果ognl以#开始,只从context查找,否则从root的栈顶对象开始往下查找,找到后不会继续往下查找,如果root找遍后也没有,再到context里查找。

函数的执行规则与上面的Ognl.setValue/Ognl.getValue一样,根据当前对象的类型来判断执行get("a")/put("a",value)还是getA()/SetA(value)。

估计ValueStack的findValue()与setValue()函数就是上面Ognl的setValue,getValue等相关函数的封装。

——————————————————————————————————————————————————

struts2标签doTag()猜想
根据struts2标签的功能和上面说明,很容易猜想到struts2标签doTag()里面的结构,下面列出几个(只是我的猜想,没确认过源代码):

<s:property />   输出root栈顶对象
{


ValueStack stack = ActionContext.getContext().getValueStack();
Object obj = stack.peek();
通过pageContext获得response的输出流对象out;
out.print(obj);
}


<s:property value="name" />
{


ValueStack stack = ActionContext.getContext().getValueStack();
Object obj = stack.findValue("name");
通过pageContext获得response的输出流对象out;
out.print(obj);
}


<s:property value="#msg.time" />
{


ValueStack stack = ActionContext.getContext().getValueStack();
Object obj = stack.findValue("#msg.time");
通过pageContext获得response的输出流对象out;
out.print(obj);
}


<s:set name="firstEmp" value="empList[0]" />  往context放入对象:
{


ActionContext ctx = ActionContext.getContext();
ValueStack stack = ActionContext.getContext().getValueStack();
Object obj =  stack.findValue("empList[0]");
ctx.put("firstEmp", obj);
}


<s:push value="empList[0]">  往root栈顶放入对象
......
</s:push>  push标签结束就把对象从root栈顶取出恢复原状
{


ValueStack stack = ActionContext.getContext().getValueStack();
Object obj = stack.findValue("empList[0]");
stack.push(obj);
......
stack.pop();
}

 

转载地址:http://lbdhb.baihongyu.com/

你可能感兴趣的文章
创建微信机器人和女朋友聊天_创建聊天机器人
查看>>
scrum master_从Scrum Master到工程副总裁:职称为何重要
查看>>
sdlc 瀑布式 生命周期_SDLC指南–软件开发生命周期的阶段和方法
查看>>
大omega记号_什么是大欧米茄符号?
查看>>
react 使用 mobx_如何使用React和MobX状态树构建基于状态的路由器
查看>>
移动认证_如何在移动设备上实施安全的生物特征认证
查看>>
敏捷开发创始人_开发人员和技术创始人如何将他们的想法转化为UI设计
查看>>
node aws 内存溢出_在AWS Elastic Beanstalk上运行生产Node应用程序的现实
查看>>
我如何在昌迪加尔大学中心组织Google Hash Code 2019
查看>>
子集和与一个整数相等算法_背包问题的一个变体:如何解决Java中的分区相等子集和问题...
查看>>
aws中部署防火墙_如何在AWS中设置自动部署
查看>>
typescript_如何掌握高级TypeScript模式
查看>>
golang底层深入_带有Golang的GraphQL:从基础到高级的深入研究
查看>>
如何选择正确的容器编排以及如何进行部署
查看>>
出现字迹模糊迹象_改变迹象:如何使用动态编程解决竞争性编程问题
查看>>
angular 渐进_如何创建具有Angular和无头CMS的渐进式Web应用程序
查看>>
Dash的快速入门将使您在5分钟内进入“ Hello World”
查看>>
cake php_如何(以及为什么)在Swinject中使用Cake Pattern
查看>>
用户体验改善案例_用户体验案例研究:建立更好的体验(重新设计“和平航空”网站)...
查看>>
nginx mozilla_我发现Mozilla的私人浏览模式存在重大缺陷。
查看>>