Uploaded image for project: 'Struts 1'
  1. Struts 1
  2. STR-2330

[taglib] Struts tags must check attribute values using isEmpty(), not against nulls



    • Type: Improvement
    • Status: Open
    • Priority: Minor
    • Resolution: Unresolved
    • Affects Version/s: 1.2.6 Beta
    • Fix Version/s: Future
    • Component/s: Tag Libraries
    • Labels:
    • Environment:
      Operating System: All
      Platform: PC
    • Bugzilla Id:


      There is an architectural problem with Struts tags used in tag files.

      As you know, in every Struts tag decision on whether attribute has a value set
      is based on comparison to null. Example:
      if (accesskey != null)

      { results.append(" accesskey=\""); results.append(accesskey); results.append("\""); }
      Where "accesskey" is an attribute of html:select tag.

      The following example shows why usage of Struts tags is substantially restricted
      in tag files because of that feature.

      The following "icon" tag renders a hyperlink based on "type" attribute (say,
      "remove" or "add"), displaying corresponding icon. It has 2 mutually exclusive
      attributes: "action" and "href" and one optional attribute "onclick".

      === icon.tagx begins ===

      <?xml version="1.0" encoding="UTF-8"?>
      <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:html="http://struts.apache.org/tags-html" version="2.0" >
      <jsp:directive.tag body-content="empty"/>
      <jsp:directive.attribute name="type" required="true" rtexprvalue="true" />
      <jsp:directive.attribute name="action" required="false" rtexprvalue="true" />
      <jsp:directive.attribute name="href" required="false" rtexprvalue="true" />
      <jsp:directive.attribute name="onclick" required="false" rtexprvalue="true" />

      <html:link action="${action}">
      <html:img page="images/${type}.gif" border="0"/>


      === icon.tagx ends ===

      Question here is how should we invoke html:link tag based on value of the
      attributes? Ok, we could use <c:choose> like:

      <c:if test="${not empty action}">
      <!-- use value of action atribute -->
      <html:link action="${action}">
      <html:img page="images/${type}.gif" border="0"/>
      <!-- use value of href atribute -->
      <html:link href="${href}">
      <html:img page="images/${type}.gif" border="0"/>

      this would be correct if we had only "action" and "href", but we also have
      "onclick". That means, that in every if/otherwise section we need to add same
      check for presence of "onclick" attribute. If we had not 3 but 10 attributes,
      then total number of <if> statements would be 2^9 which is far beyond reasonable

      The most obvious and conscious solution would be to use the following
      construction instead:

      <html:link action="${action}" href="${href}" onclick="${onclick}">
      <html:img page="images/${type}.gif" border="0"/>

      So if icon tag is invoked via <my:icon action="/Action" type="add"/> then "href"
      and "onclick" attributes would be nulls and, say, href="${href}" will not change
      the default value (null) of the html:link "href" property (call setHref(null);
      on tag handler). But this is not true because EL evaluates nulls into empty
      strings, so what happens is that html:link tag receives empty (not null) "href"
      and "onclick" properties which produces an error message (setHref(""); on tag

      The solution would be to make Struts to check attributes for emptiness (like
      StringUtils.isEmpty(), i.e. == null or ""), not just for nulls. Then it would work.

      if (StringUtils.isNotEmpty(accesskey)) { results.append(" accesskey=""); results.append(accesskey); results.append("""); }

      Where StringUtils is from jakarta commons lang package.




            • Assignee:
              vspa@mail.ru Firepica
            • Votes:
              0 Vote for this issue
              0 Start watching this issue


              • Created: