我正在尝试做一些看起来应该相对简单并且遇到一些障碍的事情。
假设我有一个产品列表,我将其作为请求属性公开,名称为products
。我们还要说每个产品都有一个id
字段,并且我还有一堆请求属性以selectedProduct_<product-id>
的形式设置,以指示选择了哪些。
我知道有更好的方法来表示这些信息,例如将所有选定的ID放入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。显然这不实用,但希望它说明了我想要实现的目标。基本上我需要:
selectedProduct_...
循环中每次迭代使用的正确forEach
值。像<c:set var="key" value="selectedProduct_${product.id}"/>
这样简单的东西可以做到这一点,除了我不知道如何接受key
并使用它来获取具有该名称的request属性的值(没有欺骗和运行文字Java代码在<% %>
区块内。)这是否可以使用纯JSP / JSTL?我知道我可以在<% %>
内部运行一些Java代码来解决这个问题,但这似乎是非常糟糕的形式。当然存在更优雅的解决方案?
答案 0 :(得分:17)
您可以使用implicit objects:
有些对象允许访问使用范围对象中描述的各种范围变量。
当表达式按名称引用其中一个对象时,将返回相应的对象而不是相应的属性。例如,$ {pageContext}返回PageContext对象,即使现有的pageContext属性包含其他一些值。
- pageScope:将页面范围的变量名称映射到其值
- requestScope:将请求范围的变量名称映射到其值
- sessionScope:将会话范围的变量名称映射到其值
- applicationScope:将应用程序范围的变量名称映射到其值
所以,例如:
<c:set var="selectedProductAttrName" value="selectedProduct_${product.id}"/>
${requestScope[selectedProductAttrName]}