8

I am using PrettyFaces in my JSF application. The site requires authentication to access some pages, so I'm using a listener (prerender view) that checks whether the user is logged in. So, if the user tries to access /foo (/foo.jsf before PrettyFaces), I redirect to /login.

However, I want to redirect them to their initial destination, so I want to attach a request parameter "next" so that I redirect the user to /login?next=/foo instead. Unfortunately, I can't get the original requestURI from the request object, the uri string in the following code is /appname/foo.jsf instead of /appname/foo

ctx = FacesContext.getCurrentInstance().getExternalContext();
HttpServletRequest request = (HttpServletRequest) ctx.getRequest();
String uri = request.getRequestURI();

Is there a way to retrieve the original URI path?

ustun
  • 6,941
  • 5
  • 44
  • 57

2 Answers2

7

PrettyFaces uses under the covers RequestDispatcher#forward() to forward a pretty URL to the real URL. Using this technique, the original request URI is available as request attribute with the key RequestDispatcher#FORWARD_REQUEST_URI.

So, this should do:

String originalURI = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);
// ...
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks a lot! It is indeed stored in the requestMap, however the key name was slightly different and given as a string. The following worked. String originalURI = (String) ctx.getRequestMap().get("javax.servlet.forward.request_uri"); – ustun Oct 12 '11 at 13:38
  • Uhm, that's the same value as `RequestDispatcher#FORWARD_REQUEST_URI`. See also the javadoc: http://download.oracle.com/javaee/6/api/constant-values.html#javax.servlet.RequestDispatcher.FORWARD_REQUEST_URI What exactly did you get when you sysout the value? Or did it just not compile? (that constant was introduced in Servlet 2.5). – BalusC Oct 12 '11 at 13:40
  • Yes, it didn't compile, complaining about missing field. Strange, I thought I was already using Servlet 2.5 (have it in the dependencies), but maybe some other old version is overriding. – ustun Oct 12 '11 at 13:47
  • Perhaps you've placed an offending `servlet-api.jar` file in `/WEB-INF/lib`? Some starters do that. See also http://stackoverflow.com/questions/4076601/how-do-i-import-the-javax-servlet-api-in-my-eclipse-project – BalusC Oct 12 '11 at 13:54
  • Thanks BalusC, I think my problem is a little different and maybe more involved, so I posted it as a separate question: http://stackoverflow.com/questions/7741986/requestdispatcher-class-of-the-servlet-package-does-not-have-forward-request-uri – ustun Oct 12 '11 at 14:51
  • Sorry, my mistake, that constant was introduced in Servlet 3.0. It is indeed not present in Servlet 2.5 (Java EE 5). See also http://download.oracle.com/javaee/5/api/javax/servlet/RequestDispatcher.html – BalusC Oct 12 '11 at 14:52
  • What happens if the request is forwarded twice? – Roger Keays Feb 12 '13 at 21:27
4

Use this code to get the original request URL:

PrettyContext.getCurrentInstance().getRequestUrl().toURL()

Rajat Gupta
  • 25,853
  • 63
  • 179
  • 294
  • In current prettyfaces the code is this PrettyContext.getCurrentInstance().getRequestURL().toURL() – Miklos Krivan May 09 '21 at 21:13
  • Comparing this answer with BalusC's above there is a small but important difference. This gives the URL without the context path but using the forward request uri from requestMap contains the contextPath and jsessionid as well if cookie is disabled. So be careful when you choose a solution. – Miklos Krivan May 09 '21 at 21:18
  • Also this solution gives the URL even there was no any prettyfaces effect. The solution based on forward_request_uri results to NULL. – Miklos Krivan May 09 '21 at 21:23