2

I have a tag that needs to have dynamically named page scoped variables.

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 --%>

and usage example

<%@ 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}" />

I need to put localAttr to tag's page scope, but jstl <c:set var='${....}'... /> does not accept dynamic names.

I currently use following scriptlet:

<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>

Are there any other approach to do that?

michael nesterenko
  • 14,222
  • 25
  • 114
  • 182

1 Answers1

1

Your technique is correct. You could use a custom tag to do it, since you are using custom tags. You could also use your technique but make it a little more readable/maintainable by doing:

<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>

but obviously that's just a preference thing.

If you were using a custom tag, it would reduce to a single line in the JSTL:

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

And you would just loop on the expressionVariables and set the context variables just like you do in your For loop above.

**

One other thought ... if you always need the pageScope variables set either right before calling custom_tags:someTag or right after calling it, you could modify that tag's code and either set the context variables in the TagSupport.doAfterBody() [if after] or BodyTagSupport.doInitBody()[if before] methods, for example.

alfreema
  • 1,308
  • 14
  • 26