Friday, November 2, 2012

JSP Expression Language and .class

This is something which I faced when using JSP-EL this week, consider the following JSP-EL statement which displays content based on the type of an object:

<c:choose>
 <c:when test="${container.class.simpleName=='TableContainer'}">
  <table>...</table>
 </c:when>
 <c:when test="${container.class.simpleName=='ListContainer'}">
  <ul>...</ul>
 </c:when>
 <c:otherwise>
  <c:out value="Wrong container Type"/>
 </c:otherwise>
</c:choose>



However if this is run on Tomcat 7.0+, you are likely to see a very unhelpful exception, along these lines:

org.apache.jasper.JasperException: /WEB-INF/tags/formlayout/display/displaycontainer.tag (line: 11, column: 1) "${container.class.simpleName=='TableContainer'}" contains invalid expression(s): javax.el.ELException: Failed to parse the expression [${container.class.simpleName=='TableContainer'}]


The actual cause of the issue is the use of the .class above - The expression language parser in Tomcat 7+ by default performs a check to ensure that all identifiers conform to Java Language specifications, since class(which is actually a shortcut for getClass()) is a java Keyword it fails the check for the name of an identifier and hence the error -

There are multiple fixes possible for this issue, the first fix is simply to use .getClass() instead of just .class -


....
 <c:when test="${container.getClass().simpleName=='TableContainer'}">
...
</c:choose>


The second fix is a more sensible one, don't depend on the type of the class, instead introduce a method in the class to describe its type and avoiding Java identifier issue altogether:


....
<c:when test="${container.type=='table'}">
...


Another fix is to soften the identifier check in Tomcat 7+, this can be done using a system property set at Tomcat startup -

org.apache.el.parser. SKIP_IDENTIFIER_CHECK

and is described in more detail here - http://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html

No comments:

Post a Comment