WebObjects 5.3.1 WORedirect Bug

I’m encountering a problem with WebObjects 5.3.1 and WORedirect. It looks like WORedirect is encoding the ampersand (&) url parameter separator, but WO is not respecting this when it extracts the values again.

You can see this behavior with this code:

In your WOComponent:

public WORedirect createDA(){
	NSMutableDictionary dict = new NSMutableDictionary();
	dict.takeValueForKey("Zero", "valueZero");
	dict.takeValueForKey(String.valueOf(1), "valueOne");
	dict.takeValueForKey("Two", "valueTwo");
	NSLog.out.appendln("Before: " + dict);
	String url = context().directActionURLForActionNamed( 
					"default", dict ); 
	WORedirect redirect = new WORedirect(context());
	NSLog.out.appendln("URL: " + url);
	redirect.setUrl(url);
	return redirect;
}

In your DirectAction Class:

public WOActionResults defaultAction() {
    NSLog.out.appendln("After: " + request().formValues());
    return pageWithName("Main");
}

You’ll see something like this in the Console:

Pre: {valueZero = "Zero"; valueTwo = "Two"; valueOne = "1"; }

URL: /cgi-bin/WebObjects/NewWOTest.woa/wa/default?valueZero=Zero&valueTwo=Two&valueOne=1

After: {valueZero = ("Zero"); amp;valueTwo = ("Two"); amp;valueOne = ("1");}

Because WO doesn’t respect the encoding when it extracts the URL values you end up with munged dictionary keys. This pretty much breaks using WORedirect to call a DirectAction. I can’t see an easy workaround.

I’m still trying to figure out if this is a problem with my setup or whether it is a bug. If it’s a bug, I’ll be very disappointed. I use WORedirect extensively in a number of apps and this’ll mean I’ll have to revert to WO 5.2.4 (again).

Update: I filed a bug on this.

Update: OK this is really ugly. But… I need this to work, so as a hack I’m adding a line to my WORedirects so they look like this:

public WORedirect createDA(){
	NSMutableDictionary dict = new NSMutableDictionary();
	dict.takeValueForKey("Zero", "valueZero");
	dict.takeValueForKey(String.valueOf(1), "valueOne");
	dict.takeValueForKey("Two", "valueTwo");
	NSLog.out.appendln("Pre: " + dict);
	String url = context().directActionURLForActionNamed( 
					"default", dict ); 
	url = url.replaceAll("&", "&");
	WORedirect redirect = new WORedirect(context());
	NSLog.out.appendln("URL: " + url);
	redirect.setUrl(url);
	return redirect;
}