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

使用ognl in表达式可能会遇到的问题

 
阅读更多
package cn;

public class A {
	
	private Integer id;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		A other = (A) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
	

}

 

<%

	A a1 = new A();
	a1.setId(1);
	A a2 = new A();
	a2.setId(2);
	
	List<A> list = new ArrayList();
	list.add(a1);
	list.add(a2);
	
	request.setAttribute("list", list);
%>

<s:iterator value="#request.list" var="a">
	<s:property value="#a in #request.list"/><br/>
</s:iterator>

</body>
</html>

 

期望输出:
true
true

但是实际是:
true

如果配置struts.el.throwExceptionOnFailure=true,那么会得到如下异常: 

invalid comparison: cn.A and cn.A - Class: ognl.OgnlOps
File: OgnlOps.java
Method: compareWithConversion

 

原因在其ognl LanguageGuide 中也说了:

写道
The ordering operators compare with compareTo() if their arguments are non-numeric and implement Comparable; otherwise, the arguments are interpreted as numbers and compared numerically. The in operator is not from Java; it tests for inclusion of e1 in e2, where e2 is interpreted as a collection. This test is not efficient: it iterates the collection. However, it uses the standard OGNL equality test.

它通过对象的compareTo去比较,且此处的in不是来自Java语言的。

 

所以如果你的对象没有实现Comparable,那么比较就会出问题,解决方案是:

1、实现Comparable来比较

2、使用集合本身自带的contains

 

其实ognl完全可以规避这个问题,通过改造ognl.OgnlOps.compareWithConversion方法:

原来是:

case NONNUMERIC:
                    if ( ( t1 == NONNUMERIC ) && ( t2 == NONNUMERIC ) )
                    {
                    	
                        if ( ( v1 instanceof Comparable ) && v1.getClass().isAssignableFrom( v2.getClass() ) )
                        {
                            result = ( (Comparable) v1 ).compareTo( v2 );
                            break;
                        }
                        throw new IllegalArgumentException( "invalid comparison: " + v1.getClass().getName()
                            + " and " + v2.getClass().getName() );
                    }
                    // else fall through

 

可以改造为如下来解决:

case NONNUMERIC:
                    if ( ( t1 == NONNUMERIC ) && ( t2 == NONNUMERIC ) )
                    {
                        if ( ( v1 instanceof Comparable ) && v1.getClass().isAssignableFrom( v2.getClass() ) )
                        {
                            result = ( (Comparable) v1 ).compareTo( v2 );
                            break;
                        }
                        result = -1;
                    }

 即最后不抛出异常,而是为-1。

 

提交问题后(https://issues.apache.org/jira/browse/WW-4230),人家觉得没改的必要,那就无所谓了,知道问题即可。

0
0
分享到:
评论
3 楼 liking_csdn 2013-11-14  
你的文章还是那么有营养!  Support
2 楼 jinnianshilongnian 2013-11-04  
Dead_knight 写道
哥们似乎雪藏了很久啊,最近又复出了?

最近做项目    不想太累了
1 楼 Dead_knight 2013-11-04  
哥们似乎雪藏了很久啊,最近又复出了?

相关推荐

Global site tag (gtag.js) - Google Analytics