【问题标题】:create variable with dynamic name创建具有动态名称的变量
【发布时间】:2025-12-05 22:55:01
【问题描述】:

我有一个标签需要动态命名的页面范围变量。

someTag.tag

<%@ tag language="java" pageEncoding="UTF-8" dynamic-attributes="expressionVariables" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ attribute name="expression" required="true" type="java.lang.String" %>

<c:out value="${expression}" /> <%-- this is just an example, I use expressions differently, they are not jsp el actually --%>

及用法示例

<%@ taglib prefix="custom_tags" tagdir="/WEB-INF/tags/custom_tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:set var="someAttr" value="someValue" />
<custom_tags:someTag expression="someMethod(#localAttr)" localAttr="${someAttr}" />

我需要将localAttr 放到标签的页面范围内,但是jstl &lt;c:set var='${....}'... /&gt; 不接受动态名称。

我目前使用以下脚本:

<c:forEach items="${expressionVariables}" var="exprVar">
    <% jspContext.setAttribute(((java.util.Map.Entry)jspContext.getAttribute("exprVar")).getKey().toString(), ((java.util.Map.Entry)jspContext.getAttribute("exprVar")).getValue()); %>
</c:forEach>

有没有其他方法可以做到这一点?

【问题讨论】:

标签: java jsp jstl jsp-tags scriptlet


【解决方案1】:

你的技术是正确的。您可以使用自定义标签来执行此操作,因为您使用的是自定义标签。您也可以使用您的技术,但通过以下方式使其更具可读性/可维护性:

<c:forEach items="${expressionVariables}" var="exprVar">
    <c:set var="key" value="${exprVar.key}"/>
    <c:set var="value" value="${exprVar.value}"/>
    <% jspContext.setAttribute(jspContext.getAttribute("key"), jspContext.getAttribute("value")); %>
</c:forEach>

但显然这只是一种偏好。

如果您使用的是自定义标签,它将在 JSTL 中减少为一行:

<custom_tags:loadPageVars expression="${expressionVariables}"/>

您只需循环表达式变量并设置上下文变量,就像您在上面的 For 循环中所做的那样。

**

另一个想法...如果您总是需要在调用 custom_tags:someTag 之前或在调用它之后立即设置 pageScope 变量,您可以修改该标签的代码并在 TagSupport.doAfterBody() 中设置上下文变量 [例如 if after] 或 BodyTagSupport.doInitBody()[if before] 方法。

【讨论】: