Thursday, June 23, 2011

Request Parameters in JSTL

Display All Request Parameters in JSTL


The following piece of JSTL code displays all request parameters on the page,
except for check-boxes and radio-buttons. They require the use of the paramValues implicit object.
<c:forEach items="${param}" var="par">
        Parameter Name/Value : <c:out value="${par.key} - ${par.value}"/>
</c:forEach>
To display session and request objects, use the following code:
<c:forEach items="${sessionScope}" var="par">
        Session object name/value : <c:out value="${par.key} - ${par.value}"/>
</c:forEach>

<c:forEach items="${requestScope}" var="par">
        Request object name/value : <c:out value="${par.key} - ${par.value}"/>
</c:forEach>

Other implicit objects include pageScope, applicationScope, header, headerValues, initParam, cookie and pageContext.


Sorting Request Parameters


A java TreeMap class that implements
SortedMap
interface allows us to construct a sorted Map.
To sort request parameters, or any other implicit objects that implement the Map interface, I built a small bean class. Here is the source code listing:
    package beans;
    import java.util.Map;
    import java.util.TreeMap;

    public class SortMap{
    private Map map;

    public Map getMap() {
        return map;
    }
    public void setMap(Map map) {
        this.map = new TreeMap(map);
    }
}

The setMap method of the bean constructs a TreeMap object from the Map argument.

Now, it's easy to pass the map of request parameters to the new bean and obtain the key-value pairs from it:

 <jsp:useBean id="sorter" class= "beans.SortMap">
    <c:set target= "${sorter}" property="map" value="${param}"/>
</jsp:useBean>

<c:forEach items="${sorter.map}" var="par">
        Parameter name/value : <c:out value="${par.key} -  ${par.value}"/>
</c:forEach>

Tuesday, May 3, 2011

JSTL Pagination

The following code can be used to paginate database query results using JSTL.

The select statement results are stored in the queryResults variable. Here is the paginator code:

<c:set var="totalCount" scope="session" value="${queryResults.rowCount}"/>
    <c:set var="perPage" scope="session" value="20"/>
    <c:set var="totalPages" scope="session" value="${totalCount/perPage}"/>

    <c:set var="pageIndex" scope="session" value="${param.start/perPage+1}"/>

   <c:if test="${!empty param.start && param.start >(perPage-1) && param.start !=0 }">
          <a href="?start=<c:out value="${param.start - perPage}"/>">Prev </a>

    </c:if>

   <c:forEach
        var="boundaryStart"
        varStatus="status"
        begin="0"
        end="${totalCount - 1}"
        step="${perPage}">
        <c:choose>
            <c:when test="${status.count>0 && status.count != pageIndex}">
                             <a href="?start=<c:out value='${boundaryStart}'/>">

                                <c:out value="${status.count}"/> |
                            </a>
            </c:when>
        <c:otherwise>
                <c:out value="${status.count}"/> |
        </c:otherwise>

        </c:choose>
    </c:forEach>

    <c:if test="${empty param.start || param.start<(totalCount-perPage)}">
          <a href="?start=<c:out value="${param.start + perPage}"/>">Next </a>

    </c:if>

The code makes heavy use of the count property of the varStatus attribute.
This attribute keeps count of the current round of the iteration.

Tuesday, August 25, 2009

JSTL Conditional Tags

I have started using the JSTL tags lately and found them extremely useful. An interesting feature of the JSTL is that you can extend the existing tags to implement your own feaures. Recently I needed a functionality to determine whether a particular date was before or later than the current date. Since I had to display different data based on the comparison result, I needed to use a structure similar to c:choose, c:when and c:otherwise tags.

The when portion of the jsp page would look like this:

<d:dateChoose>
<d:whenFuture year="${year}" month="${month}" >
<input type=text value='<c:out value="${}"/>'>
</d:whenFuture>
</d:dateChoose>

The tag would accept two arguments: year, and month. The tag should construct an instance of the Calendar class and make comparison to the current date.

First of all, you need to extend the ChooseTag, so that it would be in your package.

import org.apache.taglibs.standard.tag.common.core.ChooseTag;
public class DateChoose extends ChooseTag {
public DateChoose() {
super();
}
}

As you can see, you don't have to write any extra code for this class.

For the when tag handler, you need to extend the WhenTagSupport class. You have to implement the condition () method inherited from the abstract ConditionalTagSupport class.

import java.util.Calendar;
import javax.servlet.jsp.JspTagException;

import org.apache.taglibs.standard.tag.common.core.WhenTagSupport;
public class DateWhen extends WhenTagSupport {

private String year, month;

protected boolean condition() throws JspTagException {
Calendar cNow = Calendar.getInstance();
Calendar c = Calendar.getInstance();
int y = Integer.parseInt(year);
int m = Integer.parseInt(month);
c.set(y, m, 1);
return c.after(cNow);
}
... setMonth...method
... setYear... method

}


Here we construct a calendar object and compare it to the current date.

For the tag handler to be able to accept jstl variables and find their values, I added 2 extra methods:

private String findAttr(String attr){

String strAttr =parseVar(attr);
Object objValue =null;

if(strAttr != null){
objValue = pageContext.findAttribute(strAttr);
}
if(objValue != null)
return objValue.toString();
else
return null;
}

private String parseVar(String var){
String jstlVar=null;

if(var !=null && var.startsWith("$"))
jstlVar = var.substring(var.indexOf("{")+1, var.indexOf("}"));

return jstlVar;
}

The setYear method would go like this:

public void setYear(String year) {
String value = findAttr(year);
this.year = (value !=null)?value:year;
}

The setMonth method would be similar to the above.

Now, the good news is that we don't have to write our own handler for the <otherwise> part.
We can use the standard c:otherwise tag, so the final jsp code would look like this:

<d:dateChoose>
<d:whenFuture year="${year}" month="${month}" >
<input type=text value='<c:out value="${text}"/>'>
</d:whenFuture>
<c:otherwise>
<c:out value="${text}"/>
</c:otherwise>
</d:dateChoose>

Thursday, March 26, 2009

Generic JSTL Code That Displays Database Results

The following generic JSTL code displays database query results in a table irrespective of how many columns the ResultSet has. The table heading will contain column names.

<table width='90%'>
<tr>
<c:forEach var="columnName" items="${queryResults.columnNames}">
<th><c:out value="${columnName}"/></th>
</c:forEach>
</tr>
<c:forEach var="row" items="${queryResults.rows}">
<tr>
<c:forEach var="columnName" items="${queryResults.columnNames}">
<td><c:out value="${row[columnName]}"/></td>
</c:forEach>
</tr>
</c:forEach>
</table>


The queryResults variable holds the ResultSet.