`
jinnianshilongnian
  • 浏览: 21436104 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2405365
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2997971
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5631665
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257613
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1593281
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:249002
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5847801
Group-logo
跟我学Nginx+Lua开...
浏览量:698233
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:780585
社区版块
存档分类
最新评论

Struts2的Xwork2部分之OgnlValueStack的set与setValue的区别

阅读更多

今天早上一朋友向我咨询Struts2的Xwork2部分之OgnlValueStack的set与setValue的区别。

 

struts2版本:struts2.3.4.1

 

1、set(key, value)的实现

 public void set(String key, Object o) {
        //set basically is backed by a Map pushed on the stack with a key being put on the map and the Object being the value
        Map setMap = retrieveSetMap();
        setMap.put(key, o);
    }

    private Map retrieveSetMap() {
        Map setMap;
        Object topObj = peek();
        if (shouldUseOldMap(topObj)) {
            setMap = (Map) topObj;
        } else {
            setMap = new HashMap();
            setMap.put(MAP_IDENTIFIER_KEY, "");
            push(setMap);
        }
        return setMap;
    }

 set()的实现其实是构造一个Map(里边有一个特殊的key,MAP_IDENTIFIER_KEY),然后把key-value放入此map。通过如下代码可看出:

ActionContext ctx = ActionContext.getContext();
ValueStack vs = ctx.getValueStack();
vs.peek();

 

2、setValue(String expr, Object value)的实现其实最终委托给如下:

private void trySetValue(String expr, Object value, boolean throwExceptionOnFailure, Map<String, Object> context, boolean evalExpression) throws OgnlException {
        context.put(XWorkConverter.CONVERSION_PROPERTY_FULLNAME, expr);
        context.put(REPORT_ERRORS_ON_NO_PROP, (throwExceptionOnFailure) ? Boolean.TRUE : Boolean.FALSE);
        ognlUtil.setValue(expr, context, root, value, evalExpression);
}

javadoc: 

    /**
     * Attempts to set a property on a bean in the stack with the given expression using the default search order.
     *
     * @param expr  the expression defining the path to the property to be set.
     * @param value the value to be set into the named property
     */

 即从栈的顶部往下找,找到第一个匹配的赋值然后结束,不同于set()。

 

总结:

set(key, value):首先查找栈顶的一个特殊Map(里边有一个特殊的key,MAP_IDENTIFIER_KEY),如果找不到就创建一个,然后把对应的key-value放入。

 

setValue(String expr, Object value):从栈的顶部往下找,找到第一个匹配ognl表达式的赋值然后结束。

 

思考:

如下代码中我们往栈中添加了多少个对象?(不包括默认的添加的)

 

		ActionContext ctx = ActionContext.getContext();
		ValueStack vs = ctx.getValueStack();
		
		UserModel user = new UserModel();
		user.setUuid(123);

		vs.set("uuid", 456);
		vs.push(user);
		vs.set("uuid", 567);

答案:3个。

1、vs.set("uuid", 456);  第一个肯定往栈中压个Map

2、vs.push(user); 第二个 往栈中压user

3、vs.set("uuid", 567); 第三个 因为栈顶是user,所以再压一个

 

 

如何鉴定:可以通过vs.findValue("[0]")获取栈中数据,具体去参考struts2的官方文档。

 

ognl表达式中的:

[0]表示截取栈中从0位置开始的子集合; 假设栈中的数据是[a,b] 则结果就是[a,b]

[1]表示截取栈中从1位置开始的子集合; 假设栈中的数据是[a,b] 则结果就是[b]

以此类推。

 

 

[1].top表示截取栈中从1位置开始的子集合 并返回顶部对象(集合中的栈顶对象),即第一个。

 

此时大家可以在如jsp页面中使用:

s:debug 或者如下代码校验

 

<s:property value="[0].top.uuid"/>

<s:property value="[1].top.uuid"/>

<s:property value="[2].top.uuid"/>

 

6
6
分享到:
评论
11 楼 jinnianshilongnian 2013-05-18  
<s:property value=" '<font>123</font>' " default="120" escapeHtml="true"/><br/>
<s:property value=' "<font>123</font>" ' default="120" escapeHtml="true"/><br/>

结果都是正确的,之上我说过''在ognl里定义的是字符,其实不是完全正确


以下ognl.jjt文件中定义的部分语法:

如果长度为1  就是字符  否则就是字符串
/**
* Character and string literals, whose object value is stored in the token manager's
* "literalValue" field.
*/
MORE:
{
    "`"     : WithinBackCharLiteral
|
    "'"     { stringBuffer = new StringBuffer(); }: WithinCharLiteral
|
    "\""    { stringBuffer = new StringBuffer(); }: WithinStringLiteral
}

<WithinCharLiteral> MORE:
{
    < ESC: "\\" ( ["n","r","t","b","f","\\","'","`","\""]
                | (["0"-"3"])? ["0"-"7"] (["0"-"7"])?
                )
    >
        { charValue = escapeChar(); stringBuffer.append(charValue); }
|
    < (~["'","\\"]) >
        { charValue = image.charAt( image.length()-1 ); stringBuffer.append(charValue); }
}

<WithinCharLiteral> TOKEN:
{
    < CHAR_LITERAL: "'">
        {
           if (stringBuffer.length() == 1) {
                literalValue = new Character( charValue );
            } else {
                literalValue = new String( stringBuffer );
            }

        }
        : DEFAULT
}
10 楼 jinnianshilongnian 2013-05-18  
满手都是炸 写道
谢谢  非常感谢 

没事,你起的也够早,是在国内吗
9 楼 满手都是炸 2013-05-18  
谢谢  非常感谢 
8 楼 jinnianshilongnian 2013-05-18  
满手都是炸 写道
ognl表达式中的:
[0]表示截取栈中从0位置开始的子集合; 假设栈中的数据是[a,b] 则结果就是[a,b]
[1]表示截取栈中从1位置开始的子集合; 假设栈中的数据是[a,b] 则结果就是[b]
以此类推。


[1].top表示截取栈中从1位置开始的子集合 并返回顶部对象(集合中的栈顶对象),即第一个。


这一段怎么理解呢  能说的再详细点么 谢谢

strut2的官方文档上都有 建议看下
7 楼 jinnianshilongnian 2013-05-18  
满手都是炸 写道
ognl表达式中的:
[0]表示截取栈中从0位置开始的子集合; 假设栈中的数据是[a,b] 则结果就是[a,b]
[1]表示截取栈中从1位置开始的子集合; 假设栈中的数据是[a,b] 则结果就是[b]
以此类推。


[1].top表示截取栈中从1位置开始的子集合 并返回顶部对象(集合中的栈顶对象),即第一个。


这一段怎么理解呢  能说的再详细点么 谢谢


比如栈中的数据是
a
b
c
d

你使用<s:property value="[0]"/> 可以得到一个集合[a,b,c,d] 如果你需要栈顶数据 则可以使用<s:property value="[0].top"/>获取

如果<s:property value="[1]"/> 那么得到自己和[b,c,d] <s:property value="[1].top"/>得到b

意思就是可以使用[N] 得到栈的子集合,[N].top得到子集合的顶部数据
6 楼 满手都是炸 2013-05-18  
ognl表达式中的:
[0]表示截取栈中从0位置开始的子集合; 假设栈中的数据是[a,b] 则结果就是[a,b]
[1]表示截取栈中从1位置开始的子集合; 假设栈中的数据是[a,b] 则结果就是[b]
以此类推。


[1].top表示截取栈中从1位置开始的子集合 并返回顶部对象(集合中的栈顶对象),即第一个。


这一段怎么理解呢  能说的再详细点么 谢谢
5 楼 jinnianshilongnian 2013-05-17  
满手都是炸 写道
不论是哪一种,我们要是System.out.println(vs.findString("uuid"));  得到的都是最后一次放进去的那个值 

你把你的测试用例贴下 我测试下
4 楼 jinnianshilongnian 2013-05-17  
满手都是炸 写道
不论是哪一种,我们要是System.out.println(vs.findString("uuid"));  得到的都是最后一次放进去的那个值 

现在就是这种情况啊


ActionContext ctx = ActionContext.getContext(); 
ValueStack vs = ctx.getValueStack(); 
 
UserModel user = new UserModel(); 
user.setUuid(123); 
 
vs.set("uuid", 456); 
vs.push(user); 
vs.set("uuid", 567);

System.out.println(vs.findString("uuid"));  就是567啊
3 楼 满手都是炸 2013-05-17  
不论是哪一种,我们要是System.out.println(vs.findString("uuid"));  得到的都是最后一次放进去的那个值 
2 楼 jinnianshilongnian 2013-05-17  
qunianshilongnian 写道
        阅


1 楼 qunianshilongnian 2013-05-17  
        阅

相关推荐

Global site tag (gtag.js) - Google Analytics