Search code examples
jspjsp-tags

JSP tag file that either outputs its body or returns it in a variable


I have a custom tag in a ".tag" file that computes and outputs a value. Because I cannot post the code here, let's assume a simple example.

Content of file mytag.tag:

<@tag dynamic-attributes="dynamicParameters">
<%@attribute name="key" required="true"%> <%-- this works fine, in spite of dynamic-attributes --%>
<jsp:doBody var="bodyContent/">
<%-- ... here is some code to compute the value of variable "output" --%>
${output}

The caller can easily call it like this:

<prefix:mytag key="foo">Body content...</prefix:mytag>

This will insert the output of the tag. But I would also enable the caller to do something like this:

<prefix:mytag key="foo" var="mytagOutput">Body content...</prefix:mytag>

In this case, the output would not actually be written, but assigned to the variable "mytagOutput", which the caller then can use.

I know that the caller can achieve this by wrapping the custom tag in a c:set, but this is less elegant than simply declaring a "var". I also know that the @variable directive with the name-from-attribute can be used to achieve this. But then, I do not know if the attribute "var" has been given by the caller or not. (If given, I want to assign ${output} to that variable, otherwise I want to just write out ${output}.)

Is there a way how I can find out if the "var" attribute has been passed in or not?

Another option would be to create a second custom tag, maybe called "getMytag", which always expects the "var" attribute and just wraps the "mytag" in a c:set. If I don't find a solution here, I will go for that.

(If this question has been asked before, please point me to it. I did a quick search, but did not find a similar question.)


Solution

  • Ran into this same issue and found a way to this without a "hard-coded" variable name that has to match between .jsp and .tag.

    <%@ taglib prefix="c"   uri="http://java.sun.com/jsp/jstl/core"%><%@ 
    taglib prefix="s"       uri="http://www.springframework.org/tags" %>
    
    <jsp:directive.attribute name="someInput" type="java.lang.Object" required="true" rtexprvalue="true" description="Input object" />
    <jsp:directive.attribute name="var" type="java.lang.String" required="false" rtexprvalue="false" description="Optional return var name" />
    
    <s:eval expression="@someService.someMethod(someInput)" var="someOutput" />
    
    <c:choose>
        <c:when test="${not empty var}">
            ${pageContext.request.setAttribute(var, someOutput)}
        </c:when>
        <c:otherwise>
            ${someOutput}
        </c:otherwise>
    </c:choose>
    

    This tag can be used in two ways:

    <%-- Option 1: renders the output of the tag directly to the page --%>
    <some:tagname someInput="${yourVar}" />
    
    <%-- Option 2: stores the output of the tag in variable called "result" and lets the caller render the output on his own --%>
    <some:tagname someInput="${yourVar}" var="result" />
    <c:out value="${result}"/>