Iteration in JSP

Discussions

Web tier: servlets, JSP, Web frameworks: Iteration in JSP

  1. Iteration in JSP (3 messages)

    Hello all,

    Is there a way to do the following within a JSP page?

      for each item in a collection do
        call processItem(item)
      end


      function processItem(Item item) {
        get collection from item
        for each item in collection do
          call processItem(item)
        }
      }


    Forgive the attempt at psudo-code I hope it makes sense.

    Thanks.

    Regards,

    Stephen.
        

    Threaded Messages (3)

  2. Iteration in JSP[ Go to top ]

    You may use custom taglibs. See for example Loop tag
    on http://www.servletsuite.com/jsp.htm
  3. Iteration in JSP[ Go to top ]

    Hi,

    The following is an example on 'foreach' iteration using jsp tag library. I think this is what are you looking for. The basic idea is the foreach tag

    maintain the collection and control the iteration. In each loop, the item tag pop out an element from the enclosing foreach tag and process it. The current

    implementation accept only the class that implements java.util.collection interface such as java.util.Vector. Maybe in the next version, I will make it

    accepts other types such as array as well.

    Here is the file structure.

    /index.jsp
    /WEB-INF/web.xml
    /WEB-INF/tlds/foreach.tld
    /WEB-INF/classes/tagext/ForeachTag.class
    /WEB-INF/classes/tagext/ItemTag.class
    /WEB-INF/classes/tagext/ItemTei.class

    I develop it on J2SD1.3.1 and J2EE1.3 on WebLogic6.1. If you have any question about how it works or how these class interact please post the question again.

    About how jsp tag work in general, please buy a book.

    Try it and tell me whether you like it. I love to hear a comment.

    Chanok Charoenyooth
    chanok at mail dot com


    ===========
    /index.jsp
    ===========
    <%@ page import="java.util.*" %>
    <%@ taglib uri="/foreach" prefix="jspx" %>

    <%
      Vector myVector = new Vector();
      myVector.add(new Integer(1));
      myVector.add(new Integer(2));
    %>

    <html>

    <body>
    <p>Index page - index.jsp</p>

    <jspx:foreach collection="<%= myVector %>">
      <jspx:item ref="myItem" type="java.lang.Integer">
        <p>My number is: <%= myItem %>. The result is : <%= processItem(myItem) %></p>
      </jspx:item>
    </jspx:foreach>

    </body>
    </html>

    <%!
      private int processItem(Integer num)
      { // Do a simple demo processing. We just add the number by one and return it.
        return num.intValue() + 1;
      }
    %>

    ==============
    Sample output
    ==============
    Index page - index.jsp

    My number is: 1. The result is : 2

    My number is: 2. The result is : 3


    =========================================
    /WEB-INF/classes/tagext/ForeachTag.java
    =========================================
    package tagext;

    import java.util.*;
    import javax.servlet.jsp.*;
    import javax.servlet.jsp.tagext.*;

    /**
     * The 'foreach' tag, in conjunction with 'item' tag, provide a simple iteration
     * mechanism for jsp pages.
     */
    public class ForeachTag extends BodyTagSupport
    {
      private Collection collection;
      private int iterationCount = 0;

      public ForeachTag()
      {
      }

      public int doStartTag() throws JspTagException
      {
        // If the collection is empty, skip the tag body.
        if (collection.isEmpty())
        { return BodyTagSupport.SKIP_BODY;
        }

        // If the collection is not empty, start the iteration.
        return BodyTagSupport.EVAL_BODY_INCLUDE;
      }

      public int doAfterBody() throws JspTagException
      {
        // If the collection is empty, stop the iteration.
        // Or if, the number of iteration is more than the collection size, we also
        // stop the iteration. This feature is provided to prevent foreach without
        // item tag inside and cause infinite iteration.
        if (collection.isEmpty() || iterationCount >= collection.size())
        { return BodyTagSupport.SKIP_BODY;
        }

        // If the collection is not empty, increase the iteration count and keep
        // iterate the loop.
        iterationCount++;
        return BodyTagSupport.EVAL_BODY_AGAIN;
      }

      public Collection getCollection()
      { return this.collection;
      }

      public void setCollection(Collection collection)
      { this.collection = collection;
      }
    }


    ======================================
    /WEB-INF/classes/tagext/ItemTag.java
    ======================================
    package tagext;

    import java.util.*;
    import javax.servlet.jsp.*;
    import javax.servlet.jsp.tagext.*;

    /**
     * The 'item' tag is a child tag of 'foreach' tag which iterate through each
     * element in the collection. In each loop, the item tag pop out an element
     * from the collection and cast it to the specified class for processing.
     */
    public class ItemTag extends BodyTagSupport
    {
      public String ref;
      public String type;

      public ItemTag()
      {
      }

      /**
       * Pop out an element from an enclosing foreach tag and create a reference
       * to that element.
       */
      public int doStartTag() throws JspTagException
      {
        // Get the enclosing parent tag.
        Tag foreach = this.getParent();

        // If there is no parent tag or the enclosing parent is not foreach tag
        // , throw an exception.
        if (foreach == null || !(foreach instanceof ForeachTag))
        { throw new JspTagException("Error: 'item' tag must be enclosed by 'foreach' tag.");
        }

        // Get a collection from foreach tag.
        Collection collection = ((ForeachTag)foreach).getCollection();
        Iterator collectionItr = collection.iterator();

        if (collectionItr.hasNext())
        { // Pop the first item out of the collection.
          Object item = collectionItr.next();
          collectionItr.remove();

          // Create a reference for the current item inside the item tag.
          pageContext.setAttribute(ref, item);
        }

        return BodyTagSupport.EVAL_BODY_INCLUDE;
      }

      public String getRef()
      { return this.ref;
      }

      public String getType()
      { return this.type;
      }

      public void setRef(String ref)
      { this.ref = ref;
      }

      public void setType(String type)
      { this.type = type;
      }
    }


    ======================================
    /WEB-INF/classes/tagext/ItemTei.java
    ======================================
    package tagext;

    import javax.servlet.jsp.*;
    import javax.servlet.jsp.tagext.*;

    public class ItemTei extends TagExtraInfo
    {
      public ItemTei()
      {
      }

      /**
       * Generate variable info for 'item' tag.
       */
      public VariableInfo[] getVariableInfo(TagData data)
      {
        VariableInfo[] varInfo = new VariableInfo[1];

        // Retrieve tag property values.
        String ref = data.getAttributeString("ref");
        String type = data.getAttributeString("type");

        // Create a variable info with the name from the variable 'ref' and class
        // from the variable 'type'.
        varInfo[0] = new VariableInfo(ref, type, true, VariableInfo.NESTED);

        return varInfo;
      }
    }


    =================
    /WEB-INF/web.xml
    =================
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
                             "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

    <web-app>

      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>

      <taglib>
        <taglib-uri>/foreach</taglib-uri>
        <taglib-location>/WEB-INF/tlds/foreach.tld</taglib-location>
      </taglib>

    </web-app>

    ==========================
    /WEB-INF/tlds/foreach.tld
    ==========================
    <?xml version="1.0" encoding="UTF-8" ?>

    <!DOCTYPE taglib PUBLIC '-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN'
                            'http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd'>

    <taglib>
      <tlibversion>1.0</tlibversion>
      <jspversion>1.1</jspversion>
      <shortname>example</shortname>

      <info>Foreach simple example.</info>

      <tag>
        <name>foreach</name>
        <tagclass>tagext.ForeachTag</tagclass>
        <bodycontent>JSP</bodycontent>
        <info>For Each flow control.</info>

        <attribute>
          <name>collection</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
        </attribute>
      </tag>

      <tag>
        <name>item</name>
        <tagclass>tagext.ItemTag</tagclass>
        <teiclass>tagext.ItemTei</teiclass>
        <bodycontent>JSP</bodycontent>
        <info>Item in For Each flow control.</info>

        <attribute>
          <name>ref</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
        </attribute>

        <attribute>
          <name>type</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
        </attribute>
      </tag>

    </taglib>
  4. Iteration in JSP[ Go to top ]

    Thanks for that. This seems the solution I was groping for..