Home > Enterprise >  tag file with fully evaluated body content (like EVAL_BODY_INCLUDE)
tag file with fully evaluated body content (like EVAL_BODY_INCLUDE)

Time:11-04

I want my tag file to support full JSP code in its body.

For example, I want to write a tag file that wraps its content in a div:

dialog.tag

<%@tag pageEncoding="UTF-8" body-content="scriptless" %>

<div >
    <jsp:doBody />
</div>

And then I would like to use it like this:

use-dialog.tag

<%@tag pageEncoding="UTF-8" %>

<%@attribute name="someAttribute" type="java.lang.String" required="false" %>

<%@taglib prefix="mytaglib" uri="/WEB-INF/tlds/mytaglib" %>

<mytaglib:dialog>
    <%-- use variable in body content --%>
    Hello <%= someAttribute %>

    <%-- use other tags in body content --%>
    <mytaglib:some-other-tag someParameter="5" />
</mytaglib:dialog>

However, Scriptlets (<% ... %>) and Scriptlet Expressions (<%= ... %>) are not allowed in this case. Other available values for body-content (empty, scriptless, tagdependent) do not work either. The error message is:

Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here.


Thus composing / nesting tag files is not possible this way. I think this is a huge limitation of JSP tag files.

In contrast, in other frameworks you can compose and nest components as you please (for example reactjs).


However, by using a Java class that implements BodyTag, it is perfectly possible to evaluate the body content of the tag:

public class Dialog implements BodyTag
{
    private PageContext pageContext;

    @Override
    public void setPageContext(PageContext pageContext)
    {
        this.pageContext = pageContext;
    }

    @Override
    public int doStartTag()
    {
        try
        {
            JspWriter out = pageContext.getOut();
            out.print("<div class=\"dialog\">");
        }
        catch (Exception e) { /* Handle exception*/ }

        // Evaluate body content of this tag
        return EVAL_BODY_INCLUDE;
    }

    @Override
    public int doEndTag()
    {
        try
        {
            JspWriter out = pageContext.getOut();
            out.print("</div");
        }
        catch (Exception e) { /* Handle exception*/ }

        // Continue evaluating the rest of the JSP page
        return EVAL_PAGE;
    }

    /* implement other methods of the interface ... */
}

The Dialog.java Java class works, whereas the dialog.tag file does not allow full JSP expressions in its body. Thus my question:


Is there any way to have a tag file that evaluates its body with full JSP code support, just like EVAL_BODY_INCLUDE does when implementing BodyTag in a Java file?

CodePudding user response:

From oreilly.com:

You CANNOT use scripting code in the body of a Tag File tag

Thus, the only way to create tags that allow all JSP expressions (including nesting components) is to use a Java file that implements BodyTag.

This is a remarkable limitation of JSP tag files.

  • Related