注销消息不显示

时间:2014-04-21 15:27:41

标签: jsf session redirect message

当我从我的应用程序注销时,它没有显示我的注销消息

我有一个outputText尝试在我的视图中显示消息(<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>

这是我的支持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;
    }
}

为什么它不显示我的退出消息?

修改

退出方法:

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

退出按钮

<p:commandButton action="#{userBB.logout}" value="log out" />

3 个答案:

答案 0 :(得分:5)

  

为什么它不会显示我的退出消息?

因为您已将其指定为会话范围bean的属性,然后使会话无效并发送重定向。会话失效将破坏会话范围和存储在其中的所有对象,包括会话范围的托管bean。此后的重定向将创建一个全新的请求和会话,并且将重新创建所有会话范围的托管bean,并将所有属性设置为默认值。

这种方法存在两个问题:

  1. 使用<h:outputText>代替<h:message(s)>来显示消息。
  2. 将消息存储在会话范围中,而不是flash scope
  3. 要解决您的问题,请使用<h:message(s)>显示消息并使用FacesContext#addMessage()或者,因为您已经在使用其Messages实用程序类OmniFaces添加消息到faces上下文。您可以使用<h:messages globalOnly="true">仅显示全局消息(即具有null客户端ID的消息)。您可以使用Flash#setKeepMessages()告诉JSF将当前请求的所有消息存储在闪存范围内。

    因此,总而言之,这应该做到:

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

    @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");
        }
    
    }
    

    对于感兴趣的人来说,这就是使用“普通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");
        }
    

    重要提示是flash scope is severly broken in older Mojarra versions。你需要至少2.1.27才能摆脱所有这些问题。

答案 1 :(得分:2)

Faces.invalidateSession();

这将destroy session,因为bean是会话作用域,所有数据都将丢失。

<强>解决方案:

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

和你的xhtml

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

如果不想在网址中显示

创建另一个文件logout.xhtml(实际上logout.xhtml将与login.xhtml具有相同的代码,只需添加您想要的额外行)

答案 2 :(得分:1)

您还可以使用url参数隐藏邮件。

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

和xhtml

<h:outputText value="You have been logged out sucessfully" 
rendered="#{not empty param['logoutMsg']}"/>