2

I finally got messages passed between pages, but this is not redirecting me to the user login page (../../index.xhtml) instead it shows the forbidden page :

public String permission() throws IOException {
    FacesContext context = FacesContext.getCurrentInstance();
    Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
    String isLog = (String) sessionMap.get("isLogged");

    if(isLog != "TRUE") {

        System.out.println("*** The user has no permission to visit this page. *** ");
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Info : ", "Loggez-vous"));
        context.getExternalContext().getFlash().setKeepMessages(true);
        //context.getExternalContext().redirect("../../index.xhtml");
        return "../../index.xhtml?faces-redirect=true";


    } else {
        System.out.println("*** The session is still active. User is logged in. *** ");
    }
    return "../../index.xhtml?faces-redirect=true";
}

Of course, restriced page has this :

<f:event type="preRenderView" listener="#{userloginMB.permission()}"/>

Redirection using get external context will make the messages lost.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Chaibi Alaa
  • 1,346
  • 4
  • 25
  • 54

2 Answers2

4

Ignoring the general design problem (look here for a starting point), it seems that you mixed up the new JSF 2.2 <f:viewAction> and the old JSF 2.0/2.1 <f:event type="preRenderView"> trick.

Returning a navigation outcome as String on a GET request is only supported in <f:viewAction>, not in <f:event type="preRenderView">. For the latter you need ExternalContext#redirect() which you happened to have outcommented.

So, you should do either

<f:event type="preRenderView" listener="#{bean.onload}"/>
public void onload() throws IOException {
    // ...
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.redirect(ec.getRequestContextPath() + "/index.xhtml");
}

or

<f:metadata>
    <f:viewAction action="#{bean.onload}"/>
</f:metadata>
public String onload() {
    // ...
    return "/index.xhtml"; // Note: no need for faces-redirect=true!
}

and not mix up them.

Note that I wrote the code in such way that you can always use an /path relative to the web root without the need to fiddle with ../ nonsense.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • exactly, I used the viewAction before your answer, but using your answer somewhere else, and without the redirect, simply using the getExternalContext redirector (As you explained in the other post how viewAction isn't late in getting the response like the preEvent). Thanks anyway ! – Chaibi Alaa Sep 12 '15 at 23:13
  • In the comment you wrote `// Note: no need for faces-redirect=true!`. What if I do not want a redirect, but a page forward? – thatsIch Jul 25 '18 at 14:17
  • @thatsIch: use an URL rewrite library. – BalusC Jul 25 '18 at 16:47
0

You need to specify absolute path from the root context when using faces-redirect=true.

so your outcome string should look like:

return "/dir1/dir2/index.xhtml?faces-redirect=true";

if index.xhtml resides in (context root) i.e. Web Content/index.xhtml then use this outcome string:

return "/index.xhtml?faces-redirect=true";

if index.xhtml resides in Web Content/pages/dir2/index.xhtml then use this outcome string:

return "/pages/dir2/index.xhtml?faces-redirect=true";
AsSiDe
  • 1,826
  • 2
  • 15
  • 24
  • this goes to dir1/dir2/index.xhtml it is supposed to get BACK two directories, not forward. we have index and in same place DIR1 and DIR2 having DIR 3 and in it the Page.xhtml. We need to go from Page.xhtml to Index, we put ../../ :) – Chaibi Alaa Sep 12 '15 at 22:32
  • return "/index.xhtml?faces-redirect=true"; not working neither – Chaibi Alaa Sep 12 '15 at 22:40
  • then you can try phase listener. – AsSiDe Sep 12 '15 at 22:59
  • Already doing it, http://www.ocpsoft.org/java/persist-and-pass-facesmessages-over-page-redirects/ , no clue – Chaibi Alaa Sep 12 '15 at 23:00