Spring Binding with Lists and A Form Gotcha

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

Downloads and Response Headers

One of the developers ran into a problem with a servlet he was working on recently. In his app, he was displaying a link that would cause the app to deliver a text file that the user would be prompted to save.

All was well and good with Firefox with the following code:

private final static String MIME_TYPE = "text/plain";
ByteArrayOutputStream myDataOutputStream = (ByteArrayOutputStream)writeResultsToStream(myData);
response.setContentType(MIME_TYPE);
String filename = "downloadfile.txt";
response.addHeader("Content-disposition","attachment; filename=" + filename);
response.setContentLength(myDataOutputStream.size());
response.getOutputStream().write(myDataOutputStream.toByteArray());
response.getOutputStream().flush();

Because the data may contain confidential information, options like saving it out as a flat file were precluded. All well and good except that our in-house users who would be accessing the servlet primarily use Internet Explorer 6.

One of the other developers suggested the following change that fixed the issue when the servlet was running on Tomcat (which we use for our desktop development):
response.addHeader("Content-disposition","attachment; filename=" + filename); to
response.addHeader("Content-disposition","attachment;filename=" + filename);

Unfortunately, the problem reoccurred when the application was deployed on our Dev server running ATG Dynamo.

We determined that part of the problem also lay in some of the headers likely being passed from ATG, where this note was helpful:
“The MIME types “text/plain” and “application/octet-stream” are termed ambiguous because they generally do not provide clear indications of which application or CLSID should be associated as the content handler.”
http://msdn.microsoft.com/en-us/library/ms775147.aspx
Which I read to mean that it attempts to derive the file name from the URL, even though we’ve passed a name in the header.
Also, ‘The main problem is that Internet Explorer strictly interprets a combination of SSL (https) and “cache-control: no-cache” as “do not save encrypted pages to disk.”’
http://www.alagad.com/go/blog-entry/error-internet-explorer-cannot-download-filename-from-webserver

My suggestion (per my research) was to make the following additional changes to the header:

response.addHeader("Pragma", "public");
response.addHeader("Cache-Control", "max-age=0");

I haven’t dug into the respective application server headers and settings, but I’m definitely hoping to get the chance to compare the server configurations and the headers the browser receives.

Comments Off

Erlang or What I Learned at No Fluff Just Stuff

I just wanted to hit some of the high points from the No Fluff Just Stuff Java conference I attended over the weekend in April of 2008. A presentation I attended was on improving code quality and the presenter specifically commented that sending people to conferences is a good option. But he also made the point that the people who attend need to follow up with something like a trip report. His case in point was a company that was sending its “technical leaders” to the Java One conference, but they never reported back on the information they had gained and the things they had learned.

Not that I’m a technical leader by any stretch, but there was some really good stuff that I really want to share with everyone here. So what does that have to do with Erlang? And what the heck does Erlang have to do with UX?

Quite simply, it’s all about closures, something found in Erlang and going back to Smalltalk. That is, “…a closure is a function that is evaluated in an environment containing one or more bound variables.” (http://en.wikipedia.org/wiki/Closure_(computer_science)). Again, who cares? Well, not only are closures coming to Java (probably in Java 7 – http://fishbowl.pastiche.org/2003/05/16/closures_and_java_a_tutorial), but they already exist in Javascript. In fact, you may have used them without knowing what they are. It’s one of the ways to make Javascript object oriented since you can have this idea of functions as data and a whole host of other things. That’s part of what drives libraries (frameworks, call them what you will) like prototype, DOJO, YUI etc. http://www.jibbering.com/faq/faq_notes/closures.html

With all the talk around here about AJAX and SOA, I definitely had to get my fill of that. What I found fascinating were the side-by-side comparisons of the things you could do with DOJO, prototype and YUI (just to name a few of the Javascript frameworks out there). Tools like YSlow played a big part in looking at the overhead (page weight and all that) for using those frameworks and considerations on when to use them. There was a definite emphasis on when you might only use something on an intranet due to size constraints and only using stuff judiciously.

Another interesting thing was the difference of opinion on what constituted AJAX. One of the sessions was everything you ever wanted to know about JSON and that was seriously useful. You can do all the things that you might consider strictly AJAX-y (strict in the sense of using XML), but use JSON instead. Not only that, but using JSON actually performs better and carries less overhead since JSON converts directly to native Javascript objects like arrays. Consider this bit of sample code that calls a prototype.js function:

function validate3() {
    new Ajax.Request('/DesigningForAjax/json', {
        method: "get",
        evalJSON: true,
        sanitizeJSON: true,
        parameters: {zip: $F('zip'), city: $F('city'), state: $F('state'), secure: 'true'},
        onComplete: function(request) {
            showResults2(request.responseJSON);
        }
    })
}

Guess what? That’s JSON. But you probably knew that already. I didn’t and it really opened my eyes on how to do some really fascinating things and also some of the security issues inherent with Javascript and cross-site scripting (XSS). But JSON isn’t limited to JavaScript. It’s language-agnostic. In fact, there are a number of converters that can take JSON and convert it to XML or vice-versa. It’s equally simple to do the conversion on the client end and is a nicely defined (standards-based) way to convert stuff for use by Javascript. For example, if you want to do some things with an RSS feed on a page: http://blogs.msdn.com/shahpiyush/archive/2007/04/12/2103116.aspx (edit: previously linked to a project on John Resig’s site that’s no longer extant http://ejohn.org/blog/json-and-rss/).

Which leads me to the last session of the weekend, GIS for Web Developers. Which was pretty much a whirlwind (World Wind?) tour through all the things you can do with maps without using the Google Maps API. If you want to see how you can mash up maps to do some cool things, definitely check out OpenLayers:http://openlayers.org/

It gets even cooler if you run your own map server and everything you might want to know was covered in the session and can be as simple as deploying a WAR file on an application server. I’ll let you know when I get my custom maps up and running sometime.

We also covered a variety of things like tools to use for working with JavaScript and both Felix and John went to sessions for stuff like Spring and Maven. I also got to see some examples of rapid prototyping (live demos in the space of these hour and a half presentations of working sites with RESTful servlets and AJAX front ends) using tools like Grails.

If you’re interested in any of these topics and want to talk to me further about, I’d really enjoy that.

Incidentally, if you’re feeling left out, one of the presenters pointed out the Yahoo! Developer Network Theater wherein you can view, download, or subscribe as a podcast, to talks by some really amazing people. http://developer.yahoo.net/blogs/theater/

————————-
Previously posted on my internal work blog at Group Health on April 23, 2008 as part of a weekly UXTech build session.

Comments Off