2

我在 JSTL 中使用 EL 时遇到了一些问题,并且无法按照我的意愿访问 Java Hash Map。我知道在 EL 中,如果 Integer 被访问为 Long。我有以下我试图在 JSTL 中访问的哈希映射定义 -

Map<Long, Object> testMap = new HashMap<Long, Object>();

在 JSP 页面中,我需要检查地图是否包含特定键。我尝试通过检查是否不为空来做到这一点,如下所示 -

<c:if test='${ ! empty testMap[currObj.currVal]}'>

我还访问了代码中某处某个键的映射值,如下所示 -

<c:if test='${ testMapMap[5].data == 'something'}'>

现在的问题 -

如果我在上面定义我的地图,<Integer, Object>那么第一个 c:if 有效,但第二个失败(因为第二个尝试以 Long 形式访问它)。但是,如果我将上面的地图定义为<Long, Object>第一个 if 检查总是失败,因为它总是将其识别为空,但我检查值的第二个 if 语句有效。

有什么好方法可以确保我正确访问两个 if 语句的 HashMap 吗?我会欣赏意见。

4

1 回答 1

4

是什么currObj?您可以将其currVal成员重新定义为Long(或long)吗?


数字文字(匹配IntegerLiteralEL 语法中的产生式)将表示为Long. 该表达式的currObj.currVal计算结果为Integer。A Longnever equals()an Integer,因此一个表达式必须产生不同的类型。

本质上,您需要的是显式类型转换。EL 中没有内置这样的功能,但您可以创建一个自定义 EL 函数来为您完成。这是您在 Java 中实现的静态函数,然后在 TLD 中进行描述。我的另一个答案给出了一个包装的例子。以下是您的情况下的功能及其用法。

package com.y.taglib.core;

public final class CoercionUtil {

  public static Long toLong(Long n) {
    return n;
  }

}

TLD 如下所示:

<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0">
  <tlib-version>1.0</tlib-version>
  <short-name>x-c</short-name>
  <uri>http://dev.y.com/taglib/core/1.0</uri>
  <function>
    <description>Coerce to a java.lang.Long.</description>
    <display-name>long</display-name>
    <name>long</name>
    <function-class>com.y.taglib.core.CoercionUtil</function-class>
    <function-signature>java.lang.Long toLong(java.lang.Long)</function-signature>
  </function>
</taglib>

在您的 JSP 中:

<%@taglib uri="http://dev.y.com/taglib/core/1.0" prefix="my" %>
...
<c:if test='${ ! empty testMap[my:long(currObj.currVal)]}'>

JSP 引擎负责必要的类型强制(从方法的Integer结果currValLong所需的toLong()类型。您的方法只是为了指示所需的类型;没有它,JSP 引擎会看到参数的(已删除)类型testMap.get(Object),并且认为不需要执行任何强制,因为Integeris-an Object

于 2012-05-02T17:26:57.013 回答