I need to do string construction for URLs. Specifically URLs that I pass to formhandlers. Don't ask me if there's a better way to do it that doesn't involve stitching URLs together... it's The Standard, and so many form handlers use it it's more trouble than it's worth to do something else.
Constructing URLs is not so bad if it's just a single exit point. But this gets interesting when I have to juggle URLs for a page that has several entrance and exit points. And it becomes downright annoying when I have to maintain a context root, or pass parameters to the page to maintain state. Most of the time I can pass a referrer param through to the page so I can do a callback in JSP:
It's possible to use DSP tags inside attributes, like this:
<input type="hidden" name='index_<dsp:valueof param="index"/>' value='<dsp:valueof param="element"'/>
This is useful, as it means I don't have to do hamfisted scriptlets to jam parameters together. However, it only works in HTML attributes. Trying the following:
<dsp:input type="hidden" bean="MyFormHandler.cancelURL" value='<dsp:valueof param="referrer"/>?foo=<dsp:valueof param="foo"/>'/>
will fail. Badly. And since it's a bean thingy, it's hard to write the raw tags unless you want to get into _DARGS.
I usually do the following:
<% String url = request.getParameter("referrer"); %>
<dsp:input type="hidden" bean="MyFormHandler.cancelURL" value='<%= url + "?foo=" + request.getParameter("foo") %>'/>But I never liked it. I found a less kludgy way to do this today:
<dsp:droplet name="/atg/dynamo/droplet/Format">
<dsp:param name="format" value="{referrer}?foo={foo}&bar={bar}"/>
<dsp:param name="foo" param="foo"/>
<dsp:param name="bar" param="bar"/>
<dsp:param name="referrer" param="referrer"/>
<dsp:oparam name="output">
<dsp:input type="hidden" bean="MyFormHandler.cancelURL" paramvalue="message"/>
</dsp:oparam>
</dsp:droplet>But that's still not ideal. The ideal solution would be to use JSTL and do the following:
<dspel:input type="hidden" bean="MyFormHandler.cancelURL" value="${param.referrer + '?foo=' + param.foo}"/>or even better (using c:url as described here):
<c:url var="cancelURL" value="${param.referrer}">
<c:param name="foo" value="${param.foo}"/>
<c:param name="bar" value="${param.bar}"/>
</c:url>
<dspel:input type="hidden" bean="MyFormHandler.cancelURL" value="${cancelURL}"/>
The nice thing about using c:url is that it maintains the context path for me. If not, I have to make the referrer include the context path when I'm generating it, or insert
<dsp:param name="contextpath" bean="/OriginatingRequest.contextPath"/>
into the Format droplet.
But JSTL is only good when using straight string parameters. If I start going into beans or anything involving many.levels.of.indirection, then I have to use
The bottom line is that I don't think there's a perfect way unless JSTL can support DynamicBeans. Until that point, I'll use c:url for the simple stuff, and the Format droplet for the complex.
EDIT: Ah-ha. There's a undocumented attribute on dspel:tomap.
<dspel:tomap recursive="true" bean="Profile"/>