Get JSTL Vars from PageContext

JSTL sets its vars in the pageContext.  For example:

pageContext.setAttribute("foo", bar);


Therefore to get a JSTL variable use the pageContext within a tag or a JSP page.  For example:

// get item from pageContext and put in request
atg.servlet.DynamoHttpServletRequest drequest = atg.servlet.ServletUtil.getDynamoRequest(request);
drequest.setParameter("foo", pageContext.getAttribute("foo"));


Note that getAttribute assumes the variable is in the page scope.  If you want to get a variable from for example the request scope you would do this.

pageContext.getAttribute("foo", javax.servlet.PageContext.REQUEST_SCOPE);


For further reading please see PageContext.

Unexplainable JSP Compilation Problem

I was getting a JSP compilation problem that I could not solve.

org.apache.jasper.JasperException: Unable to compile class for JSP
        at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:510)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:375)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)

org.apache.jasper.JasperException: Unable to compile class for JSP
        at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:572)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:303)

java.lang.NumberFormatException: For input string: "${status.index}"
        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
        at java.lang.Integer.parseInt(Integer.java:447)
        at java.lang.Integer.valueOf(Integer.java:553)
        at org.apache.jasper.compiler.JspUtil.coerceToInt(JspUtil.java:752)
        at org.apache.jasper.compiler.Generator$GenerateVisitor.convertString(Generator.java:2949)

The major problem was this was happening on the server but not locally.  The compilation problem was occurring for this line.

<uportal:module definition="${module}" moduleIndex="${status.index}"/>

The moduleIndex value is “${status.index}”. Locally when the JSP compiler encounters this it knows to call my setter for moduleIndex that takes a String parameter. But on the server the JSP compiler seemed to insist on using the setter for moduleIndex that takes an integer parameter, hence the compilation problem.

I finally posted on the Sun Forums and with the help of evnafets I came up with two solutions.

  1. The correct solution is to upgrade my application to use JSTL 1.1.  Then the JSTL expressions such as “${status.index}” will be evaluated by the container.  Then I don’t have to have a setter that takes a String parameter, the JSTL expression, and evaluate it myself.  I can just use a setter that takes an integer parameter.
  2. The quick, hack solution which is to get rid of the setter that takes an integer parameter.  Wherever the application passes in an integer parameter, I change it to pass in a String representation of that integer.

Upgrading to JSTL 1.1

Based on this excellent post I came up with the following instructions for upgrading from JSTL 1.1.

  1. Update URI in JSP pages to use JSTL 1.1.
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  2. Install in WEB-INF/lib the two JSTL 1.1 jars, standard.jar and jstl.jar.  You can get these from The Jakarta Site – Standard 1.1 Taglib Downloads.
  3. Update the start of web.xml to look like this.
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
        version="2.4">

Trim White Space from JSP

Untitled | FlickrSometimes the resultant HTML from JSP files has too much white space.  This is because a lot of JSP logic will result in only a few lines of actual HTML code and the rest is white space.

One efficient way to get rid of white space is to add this configuration to your web.xml on Tomcat/JBoss as described in this article, Trim Spaces in your JSP’s HTML.

/jboss/jboss-eap-4.2/jboss-as/server/atg/deploy/jboss-web.deployer/conf/web.xml
OR
/jboss/jboss-eap-5.1/jboss-as/server/atg/deployers/jbossweb.deployer/web.xml

<servlet>
    <servlet-name>jsp</servlet-name>
    ...

    <init-param>
        <param-name>trimSpaces</param-name>
        <param-value>true</param-value>
    </init-param>

    ...
</servlet>


However this sometimes has undesired side-effects. For example this DSP:

<div class="foo">
  <dspel:valueof param="displayName" />
</div>


causes this undesired result:

<div class="foo"/>
  Frank Kim


The work around is to do this.

<dspel:getvalueof  var="displayName" param="displayName" />
<div  class="foo"><c:out  value="${displayName}"/></div>

Update 06-09-2010: The above problem might have been happening because we were running with a version of ATG that is for Servlet 2.3. When we run with a version of JBoss that runs with Servlet 2.4, e.g.  ATG 9.1 with JBoss EAP 4.2, we no longer see this problem.

There is another tip on removing white space in this JSP FAQ: Why I am getting extra whitespace in the output of my JSP?  In our code we had one file which included a bunch of tag libraries.  It originally looked like this.

<%/** Taglibs.jsp: include to pull in all taglibs */%>

<%@ taglib uri="/dspELTaglib" prefix="dspel" %>
<%@ taglib uri="/jstlCoreTaglib" prefix="c" %>
<%@ taglib uri="/struts-bean" prefix="bean" %>
<%@ taglib uri="/struts-tiles" prefix="tiles" %


When we changed it to this we saved about 5% in terms of page size in bytes.

<%@ taglib uri="/dspELTaglib" prefix="dspel"
%><%@ taglib uri="/jstlCoreTaglib" prefix="c"
%><%@ taglib uri="/struts-bean" prefix="bean"
%><%@ taglib uri="/struts-tiles" prefix="tiles" %>


You can use this tip with a DSP page and maintain indentation.

<dspel:page    ><dspel:droplet name="/betweengo/droplet/Foo"      ><dspel:oparam name="output"        >Name: <dspel:valueof param="name"      /></dspel:oparam    ></dspel:droplet
></dspel:page>

Test if empty in JSTL

Singur suflet pustiu on Flickr

(Photo: Singur suflet pustiu by dani81_const)

This article, Expression Language Overview” href=”http://www.informit.com/articles/article.aspx?p=30946″>InformIT: The JSTL Expression Language > Expression Language Overview, informed me on how to test if something is empty or not.

Empty?

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

Not empty?

<c:if test="${not empty foo}">...</c:if>

JSP redirect to another page

I found on this forum how to redirect to another page in JSP. One of the respondents explained it perfectly.

Well you have two options. Either you’ll do a server side forward or a client side redirect.
Server side forward has no interaction with the browser and therefore the URL on the location bar won’t change.
But if you do the HTTP redirect, the browser is instructed to load the other page and the contents of the location will change.
It’s your call which one to choose.

forward:

<% if (s1.equals(s2) ) { %>

     <jsp:forward page="s2.jsp"/>

<% } %>

redirect:

<% if (s1.equals(s2) ) {

    response.sendRedirect("s2.jsp");

} %>

JSTL for current URI

I was wondering how do get the current URI using JSTL and found this forum thread, JSTL EL for current page URL?.

If you want the actual URI of the JSP that is being rendered:

<c:out value="${pageContext.request.requestURI}"/>

If you want the original URI, which is probably the case, then:

<c:out value="${requestScope['javax.servlet.forward.request_uri']}"/>

In DSP if you want the original URI you can use the OriginatingRequest bean which implements the HttpServletRequest.

<dsp:valueof bean="/OriginatingRequest.requestURI" />

Size of collection in a JSP/DSP page

leaf pile on Flickr

(Photo: leaf pile by oeimah)

Sometimes in a JSP/DSP page you will want to get the size of a collection and unless you are within a Range, ForEach or similar droplet you won’t have access to this value.

Struts has a nice solution using the bean:size tag.  JSTL 1.1 has a nice solution using the fn:length function.

Here is an example of how to use Struts, DSPEL and JSTL to get the size of a collection.

  <dspel:getvalueof param="book.pages" var="pages"
                    vartype="java.util.Collection"/>
  <bean:size id="numPages" name="pages"/>
  Number of Pages: <c:out value="${numPages}"/>
  Number of Pages: <dspel:valueof value="${numPages}"/>

Here is an example of how to use JSTL 1.1 and DSPEL to get the size of a collection.

 

  <dspel:getvalueof param="book.pages" var="pages"
                    vartype="java.util.Collection"/>
  Number of Pages: <c:out value="${fn:length(pages)}"/>