开发者

How to remember original url to redirect to in case of JSF webapplication

I have a JSF web application I need to provide functionality as mentioned below:

  1. In order to comment on something user must be logged in
  2. If he is not logged in then 'Click here开发者_如何转开发 to login' takes him to the login page
  3. Successfull login must redirect him to the url from where he navigated to login page

Is there any way this can be achieved?


As per the problem, you're apparently not using container managed authentication with a realm and <security-constraint> in web.xml. It will namely handle this fully transparently for you.

I'll assume that you've homegrown a filter which redirects the user to the login page when there's no logged-in user present in the session. In that case, you need to add the current request URL as a request parameter or session attribute as well.


Here's an example which passes it as a request parameter in the filter:

if (user == null) {
    String from = URLEncoder.encode(request.getRequestURI(), "UTF-8");
    if (request.getQueryString() != null) from += "?" + request.getQueryString();
    response.sendRedirect("login.jsf?from=" + from);
}

Embed it as a hidden field in the login form (yes, using plain HTML/JSTL, JSF 1.x isn't helpful here):

<input type="hidden" name="from" value="${fn:escapeXml(param.from)}" />

In the login method, check if it is there and handle accordingly:

public String login() {
    // ...

    String from = externalContext.getRequestParameterMap().get("from");

    if (from != null && !from.isEmpty()) {
        externalContext.redirect(from);
        return null;
    } else {
        return "home"; // Default landing page after login.
    }
}

Here's an example which passes it as a session attribute in the filter:

if (user == null) {
    String from = request.getRequestURI();
    if (request.getQueryString() != null) from += "?" + request.getQueryString();
    request.getSession().setAttribute("from", from);
    response.sendRedirect("login.jsf");
}

This doesn't need a hidden field. In the login method, check if it is there and handle accordingly:

public String login() {
    // ...

    String from = externalContext.getSessionMap().get("from");

    if (from != null && !from.isEmpty()) {
        externalContext.getSessionMap().remove("from");
        externalContext.redirect(from);
        return null;
    } else {
        return "home"; // Default landing page after login.
    }
}


JSF and URLs don't work well together: JSF URLs are not bookmarkable, the URL is always one page late compared to the page you're viewing, etc... So in your case you should not think in terms of URLs but in terms of views (.xhtml) files.

One way to solve your problem is create a session managed bean that stores the current view (and associated bean parameters if any) when you are at step 2. Once the user has logged in, checks if this session bean exist, and if so, redirects the user to the stored view rather than redirecting him to the standard post-login view. This is done with a return "viewName" in your doSignIn method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜