当我从我的应用程序注销时,它没有显示我的注销消息
我有一个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" />
答案 0 :(得分:5)
为什么它不会显示我的退出消息?
因为您已将其指定为会话范围bean的属性,然后使会话无效并发送重定向。会话失效将破坏会话范围和存储在其中的所有对象,包括会话范围的托管bean。此后的重定向将创建一个全新的请求和会话,并且将重新创建所有会话范围的托管bean,并将所有属性设置为默认值。
这种方法存在两个问题:
<h:outputText>
代替<h:message(s)>
来显示消息。要解决您的问题,请使用<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']}"/>