Search code examples
jspstrutsstruts-1

logic:present not working as expected


I've condensed the code to its barest essentials to illustrate my problem as clearly as I can.

I hope the formatting turns out ok - this is my first post with stackoverflow and no matter what I did, indent 4 spaces or use ctrl-K, the compiler was not happy.

My addAssignment.jsp is showing the header "Messages" when the LinkedList should be, and appears to be, empty. If there are no messages in the LinkedList, I expect the logic:present tag to preclude the printing of the header "Messages". How do I prevent the header "Messages" from printing if there are no messages in the LinkedList?

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
  <title>Add Assignment Page</title>
  <style type="text/css">table { margin-left:5%; }</style>
</head>
<body>
  <table>
    <tr>
      <td>
        <logic:present name="messages">
          <h3>Messages:</h3>
          <logic:iterate id="msg" name="messages">
            <bean:write name="msg" /><br />
          </logic:iterate>
        </logic:present>
      </td>
    </tr>
  </table>
  <table>
    <tr>
      <td>
        <H1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add Assignment</H1>
      </td>
    </tr>
  </table>
  <html:form action="addAssignmentAction" focus="injuredWorkersFirstName">
    <table>
      <tr>
        <td>First name</td>
        <td>&nbsp;&nbsp;&nbsp;
            <html:text property="injuredWorkersFirstName" />
        </td>
      </tr>
      <tr>
        <td class="100PixCentered">&nbsp;</td>
        <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            &nbsp;&nbsp;&nbsp;&nbsp;<html:submit>submit</html:submit>
        </td>
      </tr>
    </table>
  </html:form>
</body>
</html>

The LoginAction file illustrates how I use the LinkedList. Also, the LoginAction works correctly with the Login.jsp page, the LinkedList and the Logic and Bean tags. That is, when error messages were present in the LinkedList, the Login.jsp page showed them corretly under the header Messages.

public class LoginAction extends Action {

    public void execute(Object data) { }

    public ActionForward execute(ActionMapping mapping, ActionForm form, 
             HttpServletRequest request, HttpServletResponse response) throws Exception {

        LinkedList messages = new LinkedList();
        String returnValue = "success";

        if ((((LoginForm) form).getName() == null) 
                || ((((LoginForm) form).getName()).length() == 0)) {
            messages.add("bad name");
            returnValue = "error";
        }

        if ((((LoginForm) form).getPassword() == null) 
                || ((((LoginForm) form).getPassword()).length() == 0)) {
            messages.add("bad password");
            returnValue = "error";
        }

        request.setAttribute("messages", messages);
        return mapping.findForward(returnValue);
    }
}

Struts configuration:

<struts-config>
  <data-sources></data-sources>
  <!-- ========== Form Bean Definitions =================================== -->
  <form-beans>
    <form-bean name="loginForm" type="package1.LoginForm" />
    <form-bean name="AddAssignmentForm" type="package1.AddAssignmentForm" />
  </form-beans>
  <!-- ========== Action Mapping Definitions ============================== -->
  <!-- Action Mappings Configuration -->
  <action-mappings>
    <action path="/login" type="package1.LoginAction" name="loginForm" 
        scope="request" validate="false" input="/index.jsp">
      <forward name="success" path="/addAssignment.jsp"></forward>
      <forward name="error" path="/index.jsp"></forward>
    </action>
    <action path="/addAssignmentAction" type="assignment.AddAssignmentAction" 
        name="AddAssignmentForm" scope="request" validate="false" 
        input="/addAssignment.jsp">
      <forward name="success" path="/mainMenu.jsp"></forward>
      <forward name="error" path="/addAssignment.jsp"></forward>
    </action>
  </action-mappings>
  <!-- ========== Message Resources Definitions =========================== -->
</struts-config>

Solution

  • Your expectations are wrong. As its name and documentation indicates, <logic:present> executes is body if the value is present in the request. Whether the attribute is an ampty list of not is irrelevant: the attribute is present, son the body is executed.

    You should use the <logic:notEmpty> tag instead or, even better, forget about these obsolete logic tags and use the JSTL <c:if> tag instead:

    <c:if test="${!empty messages}"> ... </c:if>