需要用el表达式取值的数据,除了对象,最好都是String类型,

修改了1小时,将HashMap<Integer , Object> 改为HashMap<String, Object>才解决问题



可以参考下文

jsp EL表达式中令人郁闷的int/float/char

    博客分类: 
  • java web
  • java开发常见问题分析

在EL表达式计算过程中,有朋友会遇到许多奇怪的问题,经常非常郁闷,在此我把这些总结一下,方便查询:

1、所有的整数数字字面量都是Long类型的;

2、所有小数字面量都是Double类型的;

3、""或''声明的是字符串,即''也是字符串,非char;

4、比较时都是equals比较。

 

接下来看几个可能出问题的例子,你会遇到一下的几个呢:

1、

如${1+2147483647} 结果是多少?

如果在java程序里边运行会得到-2147483648,而在jsp el中会得到2147483648。

 

2、

<%

    Map<Object, Object> map = new HashMap<Object, Object>();

    map.put(new Long(1), 123);

    request.setAttribute("map", map);

    request.setAttribute("a", new Long(1));

%>

${map[1]}  正确

${map[a]} 正确

 

3、

<%

    Map<Object, Object> map = new HashMap<Object, Object>();

    map.put(new Integer(1), 123);

    request.setAttribute("map", map);

    request.setAttribute("a", new Long(1));

    request.setAttribute("b", new Integer(1));

%>

${map[1]}  错误

${map[a]}  错误

${map[b]}  正确

 

4、

<%

    Map<Object, Object> map = new HashMap<Object, Object>();

    map.put(1.1, 123); //map.put(1.1d, 123);

    request.setAttribute("map", map);

    request.setAttribute("a", new Double(1.1));

%>

map.a=${map[1.1]}  正确

map.a=${map[a]}     正确

 

5、

<%

    Map<Object, Object> map = new HashMap<Object, Object>();

    map.put(1.1f, 123); //map.put(new Float(1.1), 123);

    request.setAttribute("map", map);

    request.setAttribute("a", new Double(1.1));

    request.setAttribute("b", new Float(1.1));

%>

map.a=${map[1.1]}  错误

map.a=${map[a]}     错误

map.a=${map[b]}     正确

 

6、

结合struts2的ognl表达式

<s:property value="#map = #{'a':123, 'b':234}, ''"/>  --->定义一个map,放入值栈的上下文区

<s:property value="#map['a']"/> ---------->正确,因为其支持char

${map['a']} ------------>错误, 因为'a'在jsp el表达式中是字符串,不能=char。

 

<s:property value='#map = #{"a":123, "b":234}, ""'/>  --->此时key是字符串

${map['a']}

 

此处需要注意ognl中'×××' 如果长度是1那么是Character 否则是String 可参考

http://jinnianshilongnian.iteye.com/blog/1870662

 

补充:

在EL表达式规范2.2中,定义了:

写道
■ The value of an IntegerLiteral ranges from Long.MIN_VALUE to
Long.MAX_VALUE
■ The value of a FloatingPointLiteral ranges from Double.MIN_VALUE to
Double.MAX_VALUE

 在tomcat7.0.6实现中,jasper.jar(实现了EL2.2规范):

AstFloatingPoint表示小数,AstInteger表示整数,其定义如下:

Java代码   收藏代码
  1. public final class AstInteger extends SimpleNode  
  2. {  
  3.   private volatile Number number;  
  4.   
  5.   public AstInteger(int id)  
  6.   {  
  7.     super(id);  
  8.   }  
  9.   
  10.   protected Number getInteger()  
  11.   {  
  12.     if (this.number == null) {  
  13.       try {  
  14.         this.number = new Long(this.image);  
  15.       } catch (ArithmeticException e1) {  
  16.         this.number = new BigInteger(this.image);  
  17.       }  
  18.     }  
  19.     return this.number;  
  20.   }  
  21.   
  22.   public Class<?> getType(EvaluationContext ctx)  
  23.     throws ELException  
  24.   {  
  25.     return getInteger().getClass();  
  26.   }  
  27.   
  28.   public Object getValue(EvaluationContext ctx)  
  29.     throws ELException  
  30.   {  
  31.     return getInteger();  
  32.   }  
  33. }  

 

Java代码   收藏代码
  1. public final class AstFloatingPoint extends SimpleNode  
  2. {  
  3.   private volatile Number number;  
  4.   
  5.   public AstFloatingPoint(int id)  
  6.   {  
  7.     super(id);  
  8.   }  
  9.   
  10.   public Number getFloatingPoint()  
  11.   {  
  12.     if (this.number == null) {  
  13.       try {  
  14.         this.number = new Double(this.image);  
  15.       } catch (ArithmeticException e0) {  
  16.         this.number = new BigDecimal(this.image);  
  17.       }  
  18.     }  
  19.     return this.number;  
  20.   }  
  21.   
  22.   public Object getValue(EvaluationContext ctx)  
  23.     throws ELException  
  24.   {  
  25.     return getFloatingPoint();  
  26.   }  
  27.   
  28.   public Class<?> getType(EvaluationContext ctx)  
  29.     throws ELException  
  30.   {  
  31.     return getFloatingPoint().getClass();  
  32.   }  
  33. }  

 

+ - * /实现,此处只看+的:

Java代码   收藏代码
  1. package org.apache.el.parser;  
  2.   
  3. import javax.el.ELException;  
  4. import org.apache.el.lang.ELArithmetic;  
  5. import org.apache.el.lang.EvaluationContext;  
  6.   
  7. public final class AstPlus extends ArithmeticNode  
  8. {  
  9.   public AstPlus(int id)  
  10.   {  
  11.     super(id);  
  12.   }  
  13.   
  14.   public Object getValue(EvaluationContext ctx)  
  15.     throws ELException  
  16.   {  
  17.     Object obj0 = this.children[0].getValue(ctx);  
  18.     Object obj1 = this.children[1].getValue(ctx);  
  19.     return ELArithmetic.add(obj0, obj1);  
  20.   }  
  21. }  

 其委托给ELArithmetic.add:

Java代码   收藏代码
  1. public static final DoubleDelegate DOUBLE = new DoubleDelegate();  
  2.   
  3.  public static final LongDelegate LONG = new LongDelegate();  
  4.   
  5.  private static final Long ZERO = Long.valueOf(0L);  
  6.   
  7.  public static final Number add(Object obj0, Object obj1) {  
  8.    if ((obj0 == null) && (obj1 == null))  
  9.      return Long.valueOf(0L);  
  10.    ELArithmetic delegate;  
  11.    if (BIGDECIMAL.matches(obj0, obj1))  
  12.      delegate = BIGDECIMAL;  
  13.    else if (DOUBLE.matches(obj0, obj1))  
  14.      if (BIGINTEGER.matches(obj0, obj1))  
  15.        delegate = BIGDECIMAL;  
  16.      else  
  17.        delegate = DOUBLE;  
  18.    else if (BIGINTEGER.matches(obj0, obj1))  
  19.      delegate = BIGINTEGER;  
  20.    else {  
  21.      delegate = LONG;  
  22.    }  
  23.    Number num0 = delegate.coerce(obj0);  
  24.    Number num1 = delegate.coerce(obj1);  
  25.   
  26.    return delegate.add(num0, num1);  
  27.  }  

 此处委托给了各种delegate计算,其+的实现:

Java代码   收藏代码
  1. public static final class LongDelegate extends ELArithmetic  
  2.   {  
  3.     protected Number add(Number num0, Number num1)  
  4.     {  
  5.       return Long.valueOf(num0.longValue() + num1.longValue());  
  6.     }  

 从这里我们可以看出其实现。

 

而且其规范中都规定了具体字面量的东西:

写道
1.3 Literals
There are literals for boolean, integer, floating point, string, and null in an eval-
expression.
■ Boolean - true and false
■ Integer - As defined by the IntegerLiteral construct in Section 1.19
■ Floating point - As defined by the FloatingPointLiteral construct in
Section 1.19
■ String - With single and double quotes - " is escaped as \", ' is escaped as \',
and \ is escaped as \\. Quotes only need to be escaped in a string value enclosed
in the same type of quote
■ Null - null

 

也规定了操作符的运算规则,如+ - *:

Java代码   收藏代码
  1. 1.3 Literals  
  2. There are literals for boolean, integer, floating point, string, and null in an eval-expression.  
  3.   ■ Boolean - true and false  
  4.   ■ Integer - As defined by the IntegerLiteral construct in Section 1.19  
  5.   ■ Floating point - As defined by the FloatingPointLiteral construct in  
  6. Section 1.19  
  7.   ■ String - With single and double quotes - " is escaped as \"' is escaped as \',and \ is escaped as \\. Quotes only need to be escaped in a string value enclosed in the same type of quote  
  8.   ■ Null - null  
  9.   ■ If operator is -, return A.subtract(B)  
  10.   ■ If operator is *, return A.multiply(B)  
  11.   ■ If A or B is a Float, Double,or String containing ., e,or E:  
  12.   ■ If A or B is BigInteger, coerce both A and B to BigDecimal and apply operator.  
  13.   ■ Otherwise, coerce both A and B to Double and apply operator  
  14.   ■ If A or B is BigInteger, coerce both to BigInteger and then:  
  15.   ■ If operator is +, return A.add(B)  
  16.   ■ If operator is -, return A.subtract(B)  
  17.   ■ If operator is *, return A.multiply(B)  
  18.   ■ Otherwise coerce both A and B to Long and apply operator  
  19.   ■ If operator results in exception, error  

如Integer型,直接交给前边介绍的IntegerLiteral。

 

即规范中其实已经规范了这些,但是就像java里的一些东西,虽然规范规定了(如排序时 很多人有时候使用 return a-b; 如果a是负数则可能溢出),但是还是很容易出错。


你可能感兴趣的:(需要用el表达式取值的数据,除了对象,最好都是String类型,)