ognl针对javaBean属性错误的解析方式(针对类首2位字母均为大写的情况)

在使用Struts2进行属性信息显示时,经常使用如下的显示语句:

<s:property value="xx.name"/>

而对于如上的语句,在后台则是使用ognl进行数据解析。在解析时,实际的执行代码类似于这样的处理逻辑

action.getXx().getName()

然而,在ognl里面是否是严格按照javaBean的解析方式呢,如果是这样的话,那就对了。但实际情况即不是,它自作聪明地想要自己去实际properDescripter,但却弄巧成拙(可以使用这个词)。
以下代码针对于 版本ognl 2.7.3以及3.0.5(最新的也存在这个问题)。

问题出现在获取getXx()这个方法上。对于像如下的属性声明:

public class Tx {
	private CGame cGame;

	public CGame getCGame(long[] ids) {
		return null;
	}

	public CGame getcGame() {
		return cGame;
	}
}

在执行以下代码:

                Tx t = new Tx();
		System.out.println(Ognl.getValue("cGame", t));

它并不会返回正常的cGame,而是会报一个NoSuchMethodException的错误。在上面的javaBean中,由于CGame的声明方法为首2全字母为大写,根据javaBean的特殊规定,因此 getMethod直接为首字母小写形式,而并不是简单粗暴的getCGame()形式。但ognl即直接栽到这里了。在上面的Ognl.getValue("cGame")中,ognl会去找相应的getMethod,即会调用OgnlRuntime.getMethodValue(xxx)方法,方法内部代码如下所示:

        Object result = null;
        Method m = getGetMethod(context, (target == null) ? null : target.getClass() , propertyName);
//最终会调用到 getDeclaredMethods(targetClass, propertyName, false /* find 'get' methods */);
//其中关键代码为
//以下代码在OgnlRuntime 1745行 3.0.5版本

//悲剧,强行将首字母大写了
                    String baseName = Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);

                    for (Class c = targetClass; c != null; c = c.getSuperclass()) {
                        Method[] methods = c.getDeclaredMethods();

                        for (int i = 0; i < methods.length; i++) {

                            if (!isMethodCallable(methods[i]))
                                continue;

                            String ms = methods[i].getName();

                            if (ms.endsWith(baseName)) {

因此,在以上的执行代码中,Ognl最终会找到getCCGame(long[])这个方法,并认为这个方法就是最终的方法,但由于它需要getMethod,因此它还会作一个判断,即判断参数列表为0。结果惟一的getCCgame(long[])就被排除了。最后就会报一个NoSuchMethodException错误。而我们正确的getcGame()方法,从一开始就被排除在Ognl的查找范围之外。

要解决以上的问题,方法也很简单,一是将属性名修改为首2位字母均为小写的情况,另一个方法就是再写一个叫getCGame()的方法,里面直接返回getcGame()。但这两种方法,均不是最妥的方法,但也只能这样做了。

转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/201207120001.html

相关文章:

作者: flym

I am flym,the master of the site:)

发表评论

邮箱地址不会被公开。 必填项已用*标注