一尘不染

JSP表达式语言和动态属性名称

jsp

我正在尝试做的事情似乎应该相对简单明了并且碰壁。

假设我有一个产品列表,该产品列表作为名称的request属性公开products。我们还说每个产品都有一个id字段,我还设置了一堆请求属性,selectedProduct_<product- id>以指示选择哪个。

我知道有更好的方法来表示此信息,例如将所有选定的id放入a Map并进行检查,但让我们假设由于某种原因我无权使用该方法。

因此,我想做的是products仅在selectedProduct_...为当前产品设置了属性的情况下进行迭代并发出一些标记。就像是:

<c:forEach var="product" items="${products}">
    <c:if test="${! empty selectedProduct_${product.id}}">
        <div class="productId">${product.id}</div>
    </c:if>
</c:forEach>

但是,当然这是行不通的,因为它死了${! empty selectedProduct_${product.id}}

如果将product-id硬编码到表达式中,则将起作用,例如:

${! empty selectedProduct_17}

…假设“ 17”是有效的产品ID。显然,这是不切实际的,但希望它可以说明我正在尝试实现的目标。基本上我需要:

  1. 确定selectedProduct_...要用于循环中每次迭代的正确值forEach。就像<c:set var="key" value="selectedProduct_${product.id}"/>执行此操作一样简单,除了我不确定如何key使用并使用它来获取具有该名称的request属性的值(无需在<% %>块内作弊和运行文字Java代码)。
  2. 获取我在#1中确定的名称的request属性的值。这似乎是棘手的部分。

使用纯JSP / JSTL是否可能?我知道我可以在其中运行一些Java代码<% %>来解决此问题,但是看起来这将是极其糟糕的形式。当然存在更优雅的解决方案?


阅读 220

收藏
2020-06-08

共1个答案

一尘不染

您可以使用隐式对象

有一些对象可以访问使用作用域对象中介绍的各种作用域变量。

  • pageScope:将页面范围的变量名称映射为其值
  • requestScope:将请求范围的变量名映射为其值
  • sessionScope:将会话范围的变量名映射为其值
  • applicationScope:将应用程序范围的变量名映射为其值

当表达式按名称引用这些对象之一时,将返回适当的对象而不是相应的属性。例如,即使现有的pageContext属性包含其他值,$
{pageContext}也会返回PageContext对象。

因此,例如:

<c:set var="selectedProductAttrName" value="selectedProduct_${product.id}"/>
${requestScope[selectedProductAttrName]}
2020-06-08