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),人家觉得没改的必要,那就无所谓了,知道问题即可。
相关推荐
ognl表达式 ognl表达式 ognl表达式 ognl表达式
本案例提供ognl使用详解,测试通过,只需解压放入自己WEB项目中,执行struts_ognl包内java文件即可(未提供jia包,若需要可以联系留言发至邮箱),若测试不好可以联系本人提供指导. Struts 2默认的表达式语言是OGNL...
struts2 中 OGNL表达式的使用struts2 中 OGNL表达式的使用
ognl表达式的详细教学描述,介绍如何使用ognl表达式和ognl的运行原理
ognl表达式在struts中的用法解析
JS:ognl表达式 JS:ognl表达式 JS:ognl表达式
NULL 博文链接:https://chaoyi.iteye.com/blog/2158731
NULL 博文链接:https://huguifuture.iteye.com/blog/761843
关于OGNL表达式的使用的整理以及提供的文档说明,ps:文档说明是英文的,可能需要翻译
在web开发技术中最常用到的OGNL表达式,对于ognl有点模糊的朋友,试试看思路必定会很清晰,用起来顺手。
Struts2的标签库及OGNL表达式语言
ognl表达式的用法,叫你熟练掌握ognl 表达式
主要介绍struts2.1 中的ognl中的表达式的用法
struts2中ognl表达式的用法,详细介绍了ognl表达式与struts2基本标签的结合。
个人整理的表达式与言EL和OGNL文档,希望可以对想看的人有所帮助
NULL 博文链接:https://takeme.iteye.com/blog/1668255
struts2标签和OGNL表达式struts2标签和OGNL表达式
struts2-OGNL表达式测试代码
这是一个关于struts2 的ognl标签的基本案例