Michael Edge wrote: > It seems to me that the following code will not work in Cocoon 2. > I believe it works in Cocoon 1, but for some reason the request > and response objects available within XSP for Cocoon 2 are not > HttpServletRequest and HttpServletResponse objects, but rather > some cocoon equivalents, org.apache.cocoon.environment.Response > and org.apache.cocoon.environment.Request. Unfortunately these > new classes do not include the sendRedirect method. Any ideas > how I would do this? I need to construct a URL in my code > and redirect to that URL. <xsp:logic> String url = URLEncoder.encode(url + whatever + parameters); response.sendRedirect(url); </xsp:logic>
Reply:
Don't use XSPs for flow control, use the sitemap. This is a common error with new users, that forget that it's the sitemap that manages the relations between pages.
If it's in the pages, the "flow" logic is dispersed; in the Cocoon sitemap it's easier to see, manage and change.
Even more so, sending a HTTP redirect works only reliably before any content has been delivered to the client. Because of Cocoon's pipeline model this is almost impossible to do from a XSP.
Add an Action that does this and redirect. You can write XSPAction BTW.
Better still, use the action to return the url and then do a <Redirects> in the sitemap; it makes your action more reusable.
Another reply:
I wanted to redirect according to a URL provided in one of the XML documents being processed; something like this:
<map:match pattern="my-resource"> ... <map:transform type="special-transformer"/> <map:redirect-to uri="{request-attr:my-parameter}"/> </map:match>
Here, the "special-transformer" would be based on AbstractDOMTransformer and set request attributes when it saw various things in the document. Unfortunately, the redirect is "precalculated" and the desired value for "my-parameter" never gets used.
So what I did instead was to use some arguably nasty code in my "special-transformer" to set the redirect:
import org.apache.cocoon.environment.Response; import org.apache.cocoon.environment.http.HttpResponse; // ... if (response instanceof HttpResponse) { ((HttpResponse) response).sendPermanentRedirect(target); }
This isn't nice, but there really doesn't seem to be any sane way in "vanilla" Cocoon where sitemap actions can be influenced by the content being processed. I don't want to use FlowScript, XSP or any of the peripherals.
Yet another reply:
The redirect attempted by the previous reply can be done using the cinclude transformer. In your pipeline, this looks like:
<map:transform src="redirect-include.xsl"> <map:parameter name="uri" value="{request-attr:my-parameter}"/> </map:transform> <map:transform type="cinclude"/>
The stylesheet 'redirect-include.xsl' is simply:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:param name="uri"/> <xsl:template match="/"> <ci:include src="{$uri}" xmlns:ci="http://apache.org/cocoon/include/1.0"/> </xsl:template> </xsl:stylesheet>
After cinclude has done its work, the rest of the original pipeline is executed, so you will need at least a serializer after cinclude.