1

Here is my code:

<h:form>
    <h:messages errorClass="errorMessage" infoClass="infoMessage"
                warnClass="warnMessage"></h:messages>
    <h:panelGroup id="login" layout="block" rendered="#{!securityBean.authorized}">
        <h:outputText value="login:"/>
        <h:inputText id="username" value="#{securityBean.username}"/>
        <h:outputText value="password:"/>
        <h:inputSecret id="password" value="#{securityBean.password}"/>
        <h:commandButton value="login" action="#{securityBean.login}"/>
    </h:panelGroup>

    <h:panelGroup id="logout" layout="block" rendered="#{securityBean.authorized}">
        <h:graphicImage id="img" library="img" name="login_success.jpg"/>
        <h:commandButton value="logout" action="#{securityBean.logout}"/>
    </h:panelGroup>
</h:form>

here is backing bean methods

    public Object login() throws ServletException {
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        try {
            request.login(username, password);
        } catch (ServletException e) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "An Error Occured: Login failed", null));
            e.printStackTrace();
        }
        return null;
    }

    public Object logout(){
        HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
        if(session != null){
            session.invalidate();
        }
        return null;
    }
    public boolean isAuthorized() {
        return FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal() != null &&
                FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName() != null &&
                !FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName().isEmpty();
    }

After login, logout button appears, but it works only on the second click. As you can see no ajax is used here, so this http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#AjaxRenderingOfContentWhichContainsAnotherForm can't help me.. How can I make it work correct? Thanks in advance.

vmk_student
  • 103
  • 1
  • 11
  • I use jsf 2..I found some topics where people said that this issue was fixed in jsf2..but it doesn't work.. – vmk_student Jul 23 '12 at 18:42
  • Could we see the code from where this form is being called? – kosa Jul 23 '12 at 18:43
  • does your SecurityBean is request scoped? – Elias Dorneles Jul 23 '12 at 18:46
  • Do you mean java action methods code from this two commandButtons? Or something else? – vmk_student Jul 23 '12 at 18:48
  • eljunior, yes, it is request scoped..Is it a problem? – vmk_student Jul 23 '12 at 18:52
  • yes, see my answer! the `rendered` attribute must evaluate to true in the next request too. – Elias Dorneles Jul 23 '12 at 19:00
  • I had similar issues. BalusC answer should help you, but based on application, you need to play with @form in render tags. – kosa Jul 23 '12 at 19:10
  • I feel that solution of my issue in point 5 from BalusC answer... But I can't get it..I do not completely understand what does it mean..maybe someone could explain it .. – vmk_student Jul 23 '12 at 19:40
  • Well, it just says that the `rendered` attribute must be true not only when you decide when to display a component but when you need to "process" it too. For example, if the value for your `rendered` attribute is not true for the request when you click the logout button for the first time, JSF will refuse to process it. – Elias Dorneles Jul 23 '12 at 19:53
  • But how the value of rendered attribute can be not true if I see the button on form and can press it...doesn't it mean that rendered is true? – vmk_student Jul 23 '12 at 19:59
  • If you see the component, it means that yes, eventually in the previous request rendered was set to true. But it should be true in the update-model-values phase of the next request too, for it to be processed. I'm not sure how your code would be affected by this, though... But, could you try setting an id to the logout button (so it won't be an auto-generated by JSF), and set rendered="true" for the panelGroup that wraps it? – Elias Dorneles Jul 23 '12 at 20:03
  • Ok, I'll try it tommorrow, hope that will work..thanks for your help. – vmk_student Jul 23 '12 at 20:05

2 Answers2

4

I think you have that problem because you need a redirection (using an outcome, not null) to a home page or something after logout. I had that problem, and I solved like this:

public String logout(){
    HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
    if(session != null){
        session.invalidate();
    }
    return "redirectToHomePageAfterLogout";
}

Hope this helps! :)

Serediuc Florin
  • 393
  • 1
  • 6
0

This is because the Response URL for the form submit is the same as the Request that generated it. It gives the effect that the URL is always one behind where you actually are.

You can suffix your URLs with ?faces-redirect=true to force JSF to redirect you rather than forward you.

A better overview is given here

Your logOut action should return a String() which gives the name of the page to move to after the logOut function completes, however.

8bitjunkie
  • 12,793
  • 9
  • 57
  • 70