论坛首页 Java企业应用论坛

(原创)最近发现OGNL的一个BUG 或者叫不足吧,这里贴出来希望OGNL项目组日后完善

浏览 2469 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (8) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-04-15   最后修改:2010-04-15

首先是遇到的问题:
在 struts2 中
我用 http://localhost:88/sysmanage/faqInfo.action?faq.id=20 的url提交,按照正常的ognl解析 出现以下结果

那么原因:

我的实体类的定义如下

一个泛型结构

当OGNL在解析ID的时候 id字段的类型仍然为Object 这样id就不会当成基本数据类型来解析 产生如图所示结果

详细一点:

下面来修改ognl的源码来解决这个问题(当然,应该不是最优的方案)

打开 OgnlRuntime抽象类,修改两处

 

 

   public static Method getAppropriateMethod( OgnlContext context, Object source, Object target, String methodName, String propertyName, List methods, Object[] args, Object[] actualArgs )
    {
        Method      result = null;
        Class[]     resultParameterTypes = null;

        if (methods != null) {
            for (int i = 0, icount = methods.size(); i < icount; i++) {
                Method  m = (Method)methods.get(i);
                Class[] mParameterTypes = getParameterTypes(m);
                //Generic converted Type
                Class[] mGenericparameterTypeString = {java.lang.String.class};
                if ( areArgsCompatible(args, mParameterTypes) && ((result == null) || isMoreSpecific(mParameterTypes, resultParameterTypes)) ) {
                	if(areArgsCompatibleGeneric(args,mGenericparameterTypeString)){
                        if(getConvertedTypesGeneric( context, target, m, propertyName, args, actualArgs))
                        	result = m;
                	}else{
	                    result = m;
	                    resultParameterTypes = mParameterTypes;
	                    System.arraycopy(args, 0, actualArgs, 0, args.length);
	                    for (int j = 0; j < mParameterTypes.length; j++) {
	                        Class       type = mParameterTypes[j];
	                        if (type.isPrimitive() && (actualArgs[j] == null)) {
	                            actualArgs[j] = getConvertedType(context, source, result, propertyName, null, type);
	                        }
	                    }
                	}
                    
                }
            }
        }
        if ( result == null ) {
            result = getConvertedMethodAndArgs( context, target, propertyName, methods, args, actualArgs );
        }
        return result;
    }

 由于要取到泛型的类型,增加一个方法,作用是根据泛型来转换传过来的参数使其与定义的实体对象匹配

 

    public static boolean getConvertedTypesGeneric( OgnlContext context, Object target, Member member, String propertyName, Object[] args, Object[] newArgs)
    {
        boolean         result = false;
        // get Generic Type
        Class[] parameterTypes = {(Class) ((ParameterizedType) target.getClass().getGenericSuperclass()).getActualTypeArguments()[0]};
        if (parameterTypes.length == args.length) {
            result = true;
            for (int i = 0, ilast = parameterTypes.length - 1; result && (i <= ilast); i++) {
                Object      arg = args[i];
                Class       type = parameterTypes[i];

                if (isTypeCompatible(arg, type)) {
                    newArgs[i] = arg;
                } else {
                    Object      v = getConvertedType(context, target, member, propertyName, arg, type);

                    if (v == OgnlRuntime.NoConversionPossible) {
                        result = false;
                    } else {
                        newArgs[i] = v;
                    }
                }
            }
        }
        return result;
    }
 

这里增加一个对泛型对象的处理

这样基本能解决这次问题而不影响到其他的部分,当然 也希望ognl项目组在后续版本增加对这个地方的处理

这是解决后的截图

   发表时间:2010-04-15  
从头到尾没搞明白搞的什么。OGNL到底有什么错误了?
0 请登录后投票
   发表时间:2010-04-15  
魔力猫咪 写道
从头到尾没搞明白搞的什么。OGNL到底有什么错误了?

你如果用泛型主键的话,是取不到对应的key的,而是一个key的数组。
0 请登录后投票
   发表时间:2010-04-19   最后修改:2010-04-19
OGNL以前是有不少问题,比如向它传个数字0或0.0就是死活不认。 struts2.1.8应该好了
0 请登录后投票
   发表时间:2010-04-20   最后修改:2010-05-04
joeyhacker 写道
OGNL以前是有不少问题,比如向它传个数字0或0.0就是死活不认。 struts2.1.8应该好了

可能就是这类 把基础类型包装成了引用类型导致的问题,可以跟踪进去看看。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics