jsp EL式でうっとうしいint/float/char
7977 ワード
詳細
EL式の計算の過程で、多くの奇妙な問題に遭遇する友人がいて、いつもとても憂鬱で、ここで私はこれらをまとめて、検索しやすいです:
1、すべての整数数字の字面量はLongタイプである.
2、すべての小さな数字の面量はDoubleタイプです.
3、「」または「宣言された文字列、すなわち「も文字列であり、charではない.
4、比較時はequals比較です.
次に、問題が発生する可能性のあるいくつかの例を見てみましょう.
1、
${1+
Javaプログラムで実行すると-2114748648が得られ、jsp elでは2147483648が得られます.
2、
Map map = new HashMap();
map.put(new Long(1), 123);
request.setAttribute("map", map);
request.setAttribute("a", new Long(1));
%>
${map[1]}が正しい
${map[a]}が正しい
3、
Map map = new HashMap();
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 map = new HashMap();
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 map = new HashMap();
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、
struts 2を組み合わせたognl式
----->mapを定義し、値スタックのコンテキスト領域に挿入します.
-------------->charをサポートしているため、正しい
${map['a']}--------->エラーです.'a'はjsp el式で文字列であり、=charではありません.
----->このとき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
tomcat 7.0.6実装中jasper.JAr(EL 2.2仕様を実現):
AstFloatingPointは小数を表し、AstIntegerは整数を表し、その定義は以下の通りである.
+-*/実装、ここでは+のみ:
ELArithmeticに依頼する.add:
ここでは、様々なdelegate計算、その+の実装を依頼します.
ここから私たちはその実現を見ることができる.
また、その規範には具体的な字面量が規定されています.
と書く
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
+-*などのオペレータの演算規則も規定されています.
Integer型のように、先に紹介したIntegerLiteralに直接渡します.
すなわち、仕様ではこれらが仕様されていますが、javaのもののように、仕様が規定されています(ソート時にreturn a-bを使用する人が多い場合、aが負数であればオーバーフローする可能性があります)が、エラーが発生しやすいです.
EL式の計算の過程で、多くの奇妙な問題に遭遇する友人がいて、いつもとても憂鬱で、ここで私はこれらをまとめて、検索しやすいです:
1、すべての整数数字の字面量はLongタイプである.
2、すべての小さな数字の面量はDoubleタイプです.
3、「」または「宣言された文字列、すなわち「も文字列であり、charではない.
4、比較時はequals比較です.
次に、問題が発生する可能性のあるいくつかの例を見てみましょう.
1、
${1+
2147483647
}の結果はいくらですか?Javaプログラムで実行すると-2114748648が得られ、jsp elでは2147483648が得られます.
2、
Map map = new HashMap();
map.put(new Long(1), 123);
request.setAttribute("map", map);
request.setAttribute("a", new Long(1));
%>
${map[1]}が正しい
${map[a]}が正しい
3、
Map map = new HashMap();
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 map = new HashMap();
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 map = new HashMap();
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、
struts 2を組み合わせたognl式
----->mapを定義し、値スタックのコンテキスト領域に挿入します.
-------------->charをサポートしているため、正しい
${map['a']}--------->エラーです.'a'はjsp el式で文字列であり、=charではありません.
----->このとき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
tomcat 7.0.6実装中jasper.JAr(EL 2.2仕様を実現):
AstFloatingPointは小数を表し、AstIntegerは整数を表し、その定義は以下の通りである.
public final class AstInteger extends SimpleNode
{
private volatile Number number;
public AstInteger(int id)
{
super(id);
}
protected Number getInteger()
{
if (this.number == null) {
try {
this.number = new Long(this.image);
} catch (ArithmeticException e1) {
this.number = new BigInteger(this.image);
}
}
return this.number;
}
public Class> getType(EvaluationContext ctx)
throws ELException
{
return getInteger().getClass();
}
public Object getValue(EvaluationContext ctx)
throws ELException
{
return getInteger();
}
}
public final class AstFloatingPoint extends SimpleNode
{
private volatile Number number;
public AstFloatingPoint(int id)
{
super(id);
}
public Number getFloatingPoint()
{
if (this.number == null) {
try {
this.number = new Double(this.image);
} catch (ArithmeticException e0) {
this.number = new BigDecimal(this.image);
}
}
return this.number;
}
public Object getValue(EvaluationContext ctx)
throws ELException
{
return getFloatingPoint();
}
public Class> getType(EvaluationContext ctx)
throws ELException
{
return getFloatingPoint().getClass();
}
}
+-*/実装、ここでは+のみ:
package org.apache.el.parser;
import javax.el.ELException;
import org.apache.el.lang.ELArithmetic;
import org.apache.el.lang.EvaluationContext;
public final class AstPlus extends ArithmeticNode
{
public AstPlus(int id)
{
super(id);
}
public Object getValue(EvaluationContext ctx)
throws ELException
{
Object obj0 = this.children[0].getValue(ctx);
Object obj1 = this.children[1].getValue(ctx);
return ELArithmetic.add(obj0, obj1);
}
}
ELArithmeticに依頼する.add:
public static final DoubleDelegate DOUBLE = new DoubleDelegate();
public static final LongDelegate LONG = new LongDelegate();
private static final Long ZERO = Long.valueOf(0L);
public static final Number add(Object obj0, Object obj1) {
if ((obj0 == null) && (obj1 == null))
return Long.valueOf(0L);
ELArithmetic delegate;
if (BIGDECIMAL.matches(obj0, obj1))
delegate = BIGDECIMAL;
else if (DOUBLE.matches(obj0, obj1))
if (BIGINTEGER.matches(obj0, obj1))
delegate = BIGDECIMAL;
else
delegate = DOUBLE;
else if (BIGINTEGER.matches(obj0, obj1))
delegate = BIGINTEGER;
else {
delegate = LONG;
}
Number num0 = delegate.coerce(obj0);
Number num1 = delegate.coerce(obj1);
return delegate.add(num0, num1);
}
ここでは、様々なdelegate計算、その+の実装を依頼します.
public static final class LongDelegate extends ELArithmetic
{
protected Number add(Number num0, Number num1)
{
return Long.valueOf(num0.longValue() + num1.longValue());
}
ここから私たちはその実現を見ることができる.
また、その規範には具体的な字面量が規定されています.
と書く
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
+-*などのオペレータの演算規則も規定されています.
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
■ If operator is -, return A.subtract(B)
■ If operator is *, return A.multiply(B)
■ If A or B is a Float, Double,or String containing ., e,or E:
■ If A or B is BigInteger, coerce both A and B to BigDecimal and apply operator.
■ Otherwise, coerce both A and B to Double and apply operator
■ If A or B is BigInteger, coerce both to BigInteger and then:
■ If operator is +, return A.add(B)
■ If operator is -, return A.subtract(B)
■ If operator is *, return A.multiply(B)
■ Otherwise coerce both A and B to Long and apply operator
■ If operator results in exception, error
Integer型のように、先に紹介したIntegerLiteralに直接渡します.
すなわち、仕様ではこれらが仕様されていますが、javaのもののように、仕様が規定されています(ソート時にreturn a-bを使用する人が多い場合、aが負数であればオーバーフローする可能性があります)が、エラーが発生しやすいです.