Category Archives: Struts 2

Manually Set Map Value in Struts 2

Often, the Struts 2 tag library doesn’t offer enough functionality to support a nice DHTML type of layout. In those cases, I find myself creating URLs manually to send to the action.

In most cases, this isn’t a bid deal. However, to make it work right, you have to duplicate the format that Struts uses to receive the data. For example, to send a list of items (such as List<String> names;), you would format your URL to look like


&names=johnny&names=tim&names=bill

Maps are a little harder. To create a URL to send to a map, you can use the following format:


&variableName[key]=value

Say you have the following map:

Map<Integer, Integer> userIdOrderIdMap = new HashMap<Integer, Integer>();

To set the map from Struts 2, you’d use the following URL string:


&userIdOrderIdMap[0]=1&userIdOrderIdMap[10]=15

This is the equivalent of:


userIdOrderIdMap.put(0, 1);
userIdOrderIdMap.put(10, 15);

You will probably have to manually call encodeURIComponent() on the URL string to make sure the brackets and any other special characters are escaped properly, but you already knew that, right?

You can also use a dot notation (such as &variableName.key=value), but I find that a bit counterintuitive to the way KVC types are intended to be represented.

Method Chaining and Struts

Method chaining is very cool. Basically, it allows you to turn this code:

Car hondaFit = new Car();
hondaFit.setColor(Car.Colors.BLACK);
hondaFit.setStyle(Car.Styles.SPORT);
etc.


To:

Car hondaFit = new Car().
setColor(Car.Colors.BLACK).
setStyle(Car.Styles.SPORT);

Pretty cool. It makes Java/C# style languages function similar to Ruby and it also saves some space when setting a lot of attributes at once.

Implementation is pretty simple. All you have to do is set your domain objects to return a reference pointer in their getters, setters, constructors, and whatever other methods you want to add. For example:

public class Car() {
public Car setColor(Car.Colors colorIn) { this.color = colorIn; return this; } }

There is a downside to this when using Struts, however: Struts doesn’t support method chaining for domain objects. I submitted a bug report but it doesn’t look like the Struts community is interested in changing that in order to keep their POJO implementation as clean as possible. I get that, but it is a bummer that we had to revert back to a method-chainingless implementation of our domain objects.

For reference, the error you will receive when trying to bolt Struts onto a method chained domain object backend is:


ERROR ParametersInterceptor.setParameters()204 - ParametersInterceptor - [setParameters]: Unexpected Exception caught setting '[domainProperty]' on 'class [our action]': Error setting expression '[ourExpression]' with value '[Ljava.lang.String;@81b051'

The items in [ ] I have replaced with generic descriptions of the specific values, but you get the idea.

Struts Errors: Stream Closed

struts2.pngSince February, I have been working pretty extensively in the Struts 2 framework. This is my first interaction with a Java web framework in general and with Struts in particular.

Struts, like any other web framework, has some things it does extremely well and some things that it does not so well. One of the things that falls into the “not so well” category is Struts error handling. The framework does a horrible job of communicating to the developer what is going wrong in the application.

So, over the next few weeks, I intend to post some of the more difficult errors that I’ve found to troubleshoot. Today’s error is:

java.io.IOException: Stream closed
    at org.apache.jasper.runtime.JspWriterImpl.ensureOpen(JspWriterImpl.java:257)
    at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:161)
    at org.apache.jasper.runtime.JspWriterImpl.flush(JspWriterImpl.java:219) 

This error pops up during the execution of an action that is attempting to render a JSP as part of the result. The error is displayed in Tomcat directly in the browser even though the source compiles (and creates a valid JAR) with no errors. The problem to this little gem lies in the JSP itself and, often enough, in a collection.

For example, to reproduce this error, I modified a chunk of JSP for the application I’ve been working on to say this:

<s:select name="scheme" list="#{'Tel':'tel','SIP':'sip}" required="true"/>

You’ll notice that the list itself is missing a closing quote around the second value (‘sip should be ‘sip’).

Hope that helps!