Search code examples
jspstruts2

Iterating a HashSet in a JSP using struts tag


I am new to JSP. I have a List of Employer bean object which has a property of Employee info.

   List<Employer> employerList;

   class Employer{
      private Set<EmployeeInfo> employeeInfo;

      public Set<EmployeeInfo> getEmployeeInfo() {
        return employeeInfo;
      }

     public void setEmployeeInfo(Set<EmployeeInfo> employeeInfo) {
       this.employeeInfo= employeeInfo;
     }
  }

class EmployeeInfo{
      private String name;

      public setName(String name){
         this.name=name;
      }

       public getName(){
          return name;
      }
}

I am trying to check if the employeeSetInfo is not null/empty and then display the names of each employee in a jsp using struts 2 tag.

<s:if test="%{employerList.employeeInfo.size>0}">
    <s:iterator value="employerList.employeeInfo" var="employee">
        <s:property value="#employee.name" />
    </s:iterator>
</s:if>

However, its not working.


Solution

  • A number of things, first to directly answer your question, as mentioned in a comment you need to iterate your list:

    <!-- the "test" attribute is evaluated by default so we don't need to wrap it with 
    %{}, also note that you are not testing for null so this isn't safe, your code 
    should be modified to prevent nulls, where reasonable. For this reason the
    if can be omitted-->
    
    <s:iterator value="employerList"> <!-- will push each Employer's attributes to the top of the stack exposing its values --> 
       <s:iterator value="employeeInfo"> <!-- same at other iterator -->
          <s:property value="name"/>
       </s:iterator>
    </s:iterator>
    

    Now to reduce null checking (this is just an effort to avoid crazy null checking in the JSP and isn't critical to the answer in any way)...

    Put a constructor in EmployeeInfo, and don't allow the setting of null as it doesn't make sense. Initialize the data structures during construction (static initialization is fine). Then use the getter to fetch the container and add to the list/set. Then there will be no need to check for null. You can still leave the setter for the container (set,list, whatever) but perhaps make it protected to remind you that only something close (should be in the same package should be able to directly add values and hopefully know not to assign null and other far away things have no business but to work with the public getter).

    If you don't want to do this you can wrap all those iterators and the property access as well with:

    <s:if test="something != null">
       <!-- Do stuff with verified to be safe reference -->
    </s:if>
    <s:else>
       <!-- maybe state there are no values so you aren't left wondering -->
    </s:else> 
    

    Also where you can't follow this advice (which happens often) Optional<T> comes to your rescue.