3

I have observed an interesting thing in my JSF2.1/Richfaces 4.2 application. Some how all response.sendRedirect() calls inside either Filter (or) JSF Bean action methods are not working.

If we use location.href on client side (Browser), it is working fine.

Any suggestions on what could be causing send redirect failure? I have tried below signatures.

response.sendRedirect("/appRoot/mypage.xhtml");
  or 
(HttpServletResponse) facesCtx.getResponse()).sendRedirect(((HttpServletRequest)request).getContextPath()+"/appRoot/mypage.faces");
kosa
  • 65,990
  • 13
  • 130
  • 167

2 Answers2

7

Some how all response.sendRedirect() calls inside either Filter (or) JSF Bean action methods are not working.

That can happen if the request is actually an ajax request. The webbrowser doesn't translate redirects on XMLHttpRequest to the main window at all. The JS code who's sending the ajax request is responsible for that. It needs either a special/different response so that the JS code understands that it needs to change the window location, or the JS code itself needs to be altered so that it can handle the response accordingly.

If the ajax request is initiated by JSF itself (e.g. <f:ajax> and so on) and the Java code is running inside the JSF context, then you should be using ExternalContext#redirect() instead. This autodetects if the current request is an ajax request and will return a special XML response which tells the JSF ajax engine to change the location of the window. If you're not inside the JSF context (e.g. inside a Filter), then you need to create this special XML response yourself as follows:

response.setContentType("text/xml");
response.getWriter()
    .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
    .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", url);

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Hi BalusC, Yes, all these are a4j:command calls. +1, This theory perfectly make sense. If we need to do redirect in non-JSF context (Servlet Filter), is there any way (like ExternalContext#redirect() for JSF)? – kosa Jun 08 '12 at 18:55
  • You'd need to write the special XML response yourself. See the linked question for an example. I've just copied it into the above answer. – BalusC Jun 08 '12 at 18:56
  • Got it. Make sense. Let me try. Thanks! – kosa Jun 08 '12 at 18:59
  • I must add that the answer is definitely applicable on standard JSF ajax JS API (i.e. when `` is been used). It also works on PrimeFaces that way, but I can't tell it for RichFaces. If it fails, you'd need to debug the HTTP response when some `` component triggers `ExternalContext#redirect()` and then use exactly that XML syntax instead. – BalusC Jun 08 '12 at 19:02
  • It seems working (at least for a4j:command calls). I am testing more. – kosa Jun 08 '12 at 19:03
  • Glad. It'll be fine then. RichFaces 3.x may have done it differently as that's not designed for JSF 2.x. – BalusC Jun 08 '12 at 19:04
  • BalusC, Do you see any potential violation/issues in redirecting ajax call? – kosa Jun 08 '12 at 19:09
  • Nope. It's perfectly fine if the functional requirement really requires that. There are no security implications as ajax requests are by default as per [Same Origin Policy](http://en.wikipedia.org/wiki/Same_origin_policy) only accepted for own domain only anyway. By the way, make sure that you have a check in the filter if the current request is an ajax request or not. Otherwise it may fail for synchronous requests on the filter. See also the linked "see also" answer. – BalusC Jun 08 '12 at 19:14
  • @BalusC can I redirect to an external URL via partial response? – user2918640 Jun 01 '16 at 05:17
0
FacesContext.getCurrentInstance().getExternalContext().redirect(url);
ihebiheb
  • 3,673
  • 3
  • 46
  • 55
  • Can you explain why this works and add value in comparison to the accepted answer, which already includes your code? – mabi Mar 10 '14 at 20:06