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

8

我试图做一些看似相对简单的事情,但遇到了一些困难。

假设我有一个产品列表,将其作为请求属性暴露出来,名称为products。同时,每个产品都有一个id字段,并且我还设置了一堆请求属性,形式为selectedProduct_<product-id>,以指示哪些产品已被选择。

我知道有更好的方法来表示这些信息,例如将所有选定的id放入Map并针对该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}}处中断了。
如果我在表达式中硬编码产品ID,比如:${! empty selectedProduct_17}(假设“17”是一个有效的产品ID),那么它就会起作用。显然,这并不实际,但希望这说明了我想要实现的内容。基本上,我需要:
1.确定正确的selectedProduct_...值以用于forEach循环中的每个迭代。诸如<c:set var="key" value="selectedProduct_${product.id}"/>之类的简单方法可以做到这一点,但我不知道如何使用它来获取具有该名称的请求属性的值(而不作弊并在<% %>块内运行文字Java代码)。 2.获取我在步骤1中确定的请求属性的值。这似乎是棘手的部分。
使用纯JSP/JSTL是否可能实现这一点?我知道我可以在<% %>中运行一些Java代码来解决这个问题,但这似乎会极大地影响形式。肯定有更优雅的解决方案存在吧?
1个回答

20

您可以使用隐含对象来实现:

有些对象允许访问描述使用作用域对象中的各种变量:

  • pageScope:将页面范围的变量名称映射到其值
  • requestScope:将请求范围的变量名称映射到其值
  • sessionScope:将会话范围的变量名称映射到其值
  • applicationScope:将应用程序范围的变量名称映射到其值
当表达式按名称引用其中之一时,将返回适当的对象,而不是相应的属性。例如,${pageContext}返回PageContext对象,即使存在一个包含其他某些值的pageContext属性。

因此,例如:

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

仍然在2021年有效! - GavinBrelstaff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接