Tuesday
Apr 10, 2012
11:10 am
Filed under Java, JSP, JSTL, Web Development
For added flexibility, we’ve wanted to convert our non-application JSP page to PHP for some time now. In redesigning elements to be reusable, one of the things they incorporate is the ability to pass a value from a page to an included component, making the component generic and reusable and giving the page developer the ability to easily add custom elements like the names of script files or meta tag information.
Since we haven’t rolled that out yet and also wanted to use some of the same functionality in one of our applications, I worked out the following methods to pass that information to the page using JSPs. For specific elements, it’s easy enough to pass the information just using Java Tiles. In order to pass the parameters to the include, the Tiles include looks like this (note the pathing should be appropriate to the actual location of the included tile):
<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>
<tiles:insertTemplate template="include/head.jsp" flush="true">
<tiles:putAttribute name="title" value="This is my page"/>
<tiles:putAttribute name="description" value="This is the page description"/>
<tiles:putAttribute name="keywords" value="meta, tag, keyword, new keyword"/>
</tiles:insertTemplate>
And the values can be extracted in the include (head.jsp in this case):
<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>
<title><tiles:getAsString name="title"/></title>
<meta name="description" content="<tiles:getAsString name="description"/>" />
<meta name="keywords" content="<tiles:getAsString name="keywords"/>" />
It’s a little more complex if you want to include a collection, such as a list of scripts to iterate through and include in a tile. In that case, you
<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>
<tiles:insertTemplate template="include/footer.jsp" flush="true">
<tiles:putListAttribute name="scripts">
<tiles:addAttribute type="string" value="js/specialscriptfile.js" />
<tiles:addAttribute type="string" value="js/anotherspecialscriptfile.js" />
<%-- additional script files would go here --%>
</tiles:putListAttribute>
</tiles:insertTemplate>
The included script file names will be passed to the include by Tiles as a Java List that you can then iterate through. I prefer JSTL, so that’s the example here, though I imagine you could use a Struts iterate tag or whatever method you wished to avail yourself of (even a Java scriptlet,if you were so inclined, despite that being a bad practice).
<%@ taglib uri="/WEB-INF/tiles.tld" prefix="tiles" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%-- Scripts load here as a Yslow recommended best practice (for non-blocking requests) --%>
<tiles:insertTemplate template="scripts.jsp" flush="true" />
<%-- Scripts included from page using put-list-attribute --%>
<tiles:useAttribute id="list" name="scripts" classname="java.util.List" ignore="true"/>
<c:forEach var="item" items="${list}">
<script type="text/javascript" src="<tiles:insertAttribute value="${item}" flush="true" />"></script>
</c:forEach>
Comments Off
Friday
Oct 14, 2011
4:14 pm
Filed under Java, JSP, JSTL
Being a traditionalist, I tend to forget some of the things you can do with tag libraries like JSTL above and beyond simple things like outputting information. A colleague asked me about putting the current year on a page and my first response was something like this:
<%@ page import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt"%>
<%
Date date = new java.util.Date();
pageContext.setAttribute("date", date);
%>
<c:set var="date" value="${date}" />
<fmt:formatDate pattern="yyyy" value="${date}" />
It’s quite obvious looking at it that there’s a bit of redundancy in setting the date with a scriptlet and then making it available to JSTL to output with the Format tag library. That’s when I came across the solution to use the JSP useBean tag with JSTL resulting in the much simpler solution as follows:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<jsp:useBean id="now" class="java.util.Date" />
<fmt:formatDate var="year" value="${now}" pattern="yyyy" />
<c:out value="${year}" />
I don’t believe it has any version dependencies (as I’ve encountered with some of the JSTL libraries that only work with the JSP 2.0 spec and the like) and certainly feels cleaner. Most importantly, it gets rid of the scriptlet and, in the JSP world, that’s a win.
Comments Off
Thursday
Oct 23, 2008
10:23 am
Filed under JSP, Spring
Suppose we have an application that uses two kinds of beans: a Subscriber bean and a Dependent bean. We have a form that is used to edit the Subscriber and each Subscriber may have zero or more Dependents who are also editable. All the fields for Subscriber have been bound with Spring <form:form> tags. However, the dependents are a list of beans. What we want is dynamic binding with a List of objects. Fortunately, iterating through the objects is made easier with the use of JSTL. The only tricky part is making sure the right form elements are bound to the right dependents.
In order to accomplish that, the code looks something like this:
<form:form commandName = "myCommandObject" method = "post" cssClass = "aForm" id = "aSearchForm">
<h1>The subscriber</h1>
<p>
<form:input path = "subscriberObject.firstName" size = "15"/>
</p>
<p>
<form:input path = "subscriberObject.lastName" size = "20"/>
</p>
<p>
<form:radiobutton path = "subscriberObject.gender" value = "F"/>
Female
<form:radiobutton path = "subscriberObject.gender" value = "M"/>
Male
</p>
<p>
<label>
<form:checkbox path = "subscriberObject.currentSubscriber" value = "Y"/>
Current subscriber
</label>
</p>
<c:choose>
<c:when test = "${empty myCommandObject.subscriberObject.dependentObjects}">
<p>No dependents listed</p>
</c:when>
<c:otherwise>
<c:forEach items = "${myCommandObject.subscriberObject.dependentObjects}" var = "dependent" varStatus = "dependentRow">
<form:input path = "subscriberObject.dependentObject[${dependentRow.index}].firstName" size = "15"/>
<form:input path = "subscriberObject.dependentObject[${dependentRow.index}].lastName" size = "20"/>
<p>
<form:radiobutton path = "subscriberObject.dependentObject[${dependentRow.index}].gender" value = "F"/>
Female
<form:radiobutton path = "subscriberObject.dependentObject[${dependentRow.index}].gender" value = "M"/>
Male
</p>
<p>
<label>
<form:checkbox path = "subscriberObject.dependentObject[${dependentRow.index}].currentSubscriber" value = "Y"/>
Current subscriber
</label>
</p>
</c:forEach>
</c:otherwise>
</c:choose>
<input class = "buttonStyle" value = "submit" type = "submit"/>
</form:form>
Now for the gotcha. It turns out that the gender value for dependents may come back as either “F” or “Female” and “M” or “Male”. As near as I can tell, Spring MVC determines whether the radio button is selected based on whether the bound value matches the radio button value. In the form above, if subscriberObject.dependentObject[${dependentRow.index}].gender is set to “Female”, neither radio button will be selected.
The following (old-school) binding is therefore necessary:
<spring:bind path="eligibilityCommand.subscriberObject.dependentObject[ ${dependentRow.index} ].gender">
<input type="radio" name="<c:out value="${status.expression}"/>" value="F"<c:if test="${status.value=='F'||status.value=='Female'}"> checked="checked"</c:if> /> Female
<input type="radio" name="<c:out value="${status.expression}"/>" value="M"<c:if test="${status.value=='M'||status.value=='Male'}"> checked="checked"</c:if> /> Male
</spring:bind>
The subscriber object in the form only contains a List of dependents since the form is not dynamic (the user cannot add or remove dependents on the fly). If that were the case, it would have to use LazyList. Matt Fleming has this post and this one about dynamic list binding.
Comments Off