Pregunta

When I logout from my application it doesn't show my logout message

I have an outputText trying to show the message in my view (<h:outputText id="message" value="#{loginMB.message}" />):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:o="http://omnifaces.org/ui"
    xmlns:p="http://primefaces.org/ui"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="/WEB-INF/templates/template.xhtml">
    <ui:define name="content">
        <o:form id="login" includeViewParams="true">
            <h:outputText id="message" value="#{loginMB.message}" />
            ... Another components ...
        </o:form>
    </ui:define>
</ui:composition>

And this is my backing bean:

@ManagedBean
@SessionScoped
public class UserBB implements Serializable {

    private String message;

    public void logout() {
        try {
            message = "You have been logout successfully";

            SecurityUtils.getSubject().logout();
            Faces.invalidateSession();
            Faces.redirect("login.xhtml");
        } catch (Exception exception) {
            ... Another code ...
        }
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

Why it doesn't show my logout message?

Edit:

Logout method:

public void logout() {
    SecurityUtils.getSubject().logout();
    Messages.addFlashGlobalInfo("You have successfully log out");
    Faces.invalidateSession();
    Faces.redirect("login.xhtml?faces-redirect=true&lo=t");
}

logout button:

<p:commandButton action="#{userBB.logout}" value="log out" />
¿Fue útil?

Solución

Why it doesn't show my logout message?

Because you've assigned it as a property of a session scoped bean and are then invalidating the session and sending a redirect. The invalidation of the session will destroy the session scope and all objects stored in it, including session scoped managed beans. The redirect thereafter will create a brand new request and session and all session scoped managed beans will be newly recreated, with all properties set to default.

There are 2 problems with this approach:

  1. Using <h:outputText> instead of <h:message(s)> to display the message(s).
  2. Storing the message in the session scope instead of the flash scope.

To solve your problem, use <h:message(s)> to display the message(s) and use FacesContext#addMessage() or, as you're already using OmniFaces, its Messages utility class, to add a message to the faces context. You can use <h:messages globalOnly="true"> to display only global messages (i.e. those with a null client ID). You can use Flash#setKeepMessages() to tell JSF to store all messages of the current request in the flash scope instead.

Thus, all in all, this should do:

<h:messages id="messages" globalOnly="true" />

with

@ManagedBean
@RequestScoped // Doesn't need to be session scoped for the particular task.
public class UserManager {

    public void logout() throws Exception {
        SecurityUtils.getSubject().logout();
        Messages.addFlashGlobalInfo("You have been logged out successfully");
        Faces.invalidateSession();
        Faces.redirect("login.xhtml");
    }

}

For the interested, here's how it would look like using "plain JSF":

    public void logout() throws Exception {
        SecurityUtils.getSubject().logout();
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage("You have been logged out successfully"));
        ExternalContext externalContext = context.getExternalContext();
        externalContext.getFlash().setKeepMessages(true);
        externalContext.invalidateSession();
        externalContext.redirect("login.xhtml");
    }

Important note is that the flash scope is severly broken in older Mojarra versions. You need a minimum of 2.1.27 to get rid of all those problems.

Otros consejos

Faces.invalidateSession();

This will destroy the session and since the bean is session scoped all the data will be lost.

Solution:

 Faces.redirect("login.xhtml?msg=You have been logged out sucessfully");

and in your xhtml

<h:outputText id="message" value="#{param['msg']}"/>

If not want to show in url

Create another file logout.xhtml (Actually logout.xhtml will have same code as login.xhtml just add extra line you want)

you can also hide the mesage with url paramter.

Faces.redirect("login.xhtml?faces-redirect=true&logoutMsg=true");

and xhtml

<h:outputText value="You have been logged out sucessfully" 
rendered="#{not empty param['logoutMsg']}"/>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top