Weld strips off query parameters in case of a programmatic redirect
marcelkolsteren Mar 24, 2011 7:43 PMSometimes it's necessary, or convenient, to redirect to another page using programmatic redirect, which looks like this in a backing bean method:
FacesContext.getCurrentInstance().getExternalContext().redirect("/app/Output.faces?param1=foo");
When this redirect is handled while a long-running conversation is active, Weld steps in to add the cid
parameter to the query string. However, a side-effect of adding the cid
parameter, is that the other parameters are gone, which I think is a bug. I can also point out where the bug is. Weld uses a ConversationPropagationFilter, which wraps the response in order to override the sendRedirect method:
@Override public void sendRedirect(String path) throws IOException { ConversationContext conversationContext = instance().select(HttpConversationContext.class).get(); if (conversationContext.isActive()) { Conversation conversation = conversationContext.getCurrentConversation(); if (!conversation.isTransient()) { path = new FacesUrlTransformer(path, FacesContext.getCurrentInstance()).toRedirectViewId().toActionUrl().appendConversationIdIfNecessary(conversationContext.getParameterName(), conversation.getId()).encode(); } } super.sendRedirect(path); }
The toActionUrl() of the FacesUrlTransformer calls getActionURL on the view handler, but passes a viewId which is in fact a complete URL. The getActionURL method handles the URL as if it were a viewId, and replaces everything after the dot with faces
, thus wiping off the query string.
This can be reproduced easily with an example Maven project that I uploaded here:
The application can be built with Maven 3 and deployed on JBoss AS 6.0.0 (which includes Weld 1.1.Beta2). The application runs on this URL:
http://localhost:8080/redirectproblem/Input.faces
The input page asks the user for an input value, which is then passed on to a second page using programmatic redirect with a single query parameter. One button does the redirect after starting a long-running conversation, the other button without doing so. The former button triggers the problem, the second button just works fine.
I checked the latest Weld code, and the problem is still there.
Am I right that this is a bug, or do I overlook something?