一个 Java EE 8/SE 8 Web 应用程序在 Glassfish 5 build 25 生产和开发上运行,使用 jsf 2.3。用户创建帐户并登录。有一个“注销”按钮用于注销。
问题:“注销”按钮在网站上的任何地方都按预期工作。除了主页 (example.com) 和 (example.com/home.xhtml)。我的本地计算机上不存在该问题。仅在生产中(example.com)。
所以我有一个名为: index.xhtml 的模板。所有页面都使用它,包括 home.xhtml:
<ui:composition template="index.xhtml">
<ui:define name="top-bar">
<c:if test="#{request.remoteUser ne null}">
<h:form ><h:commandButton value="Log out" action="#{registerAdvanced.logout}"/></h:form>
</c:if>
</ui:define>
和
@Named
@RequestScoped
public class RegisterAdvanced extends BaseBacking implements Serializable {
public String logout() {
try {
getRequest().logout();
getContext().getExternalContext().getSessionMap().remove("user");
return REDIRECT_PAGE;
} catch (ServletException ex) {
return REDIRECT_PAGE;
}
}
}
用户登录和注销相当容易,直到我注意到单击主页(home.xhtml)上的注销会打印空指针异常并重定向到 404 错误页面。
[[/home.xhtml @450,77 value="#{passesTestBean.displayPassSummaryList}": java.lang.NullPointerException
javax.el.ELException: /home.xhtml @450,77 value="#{passesTestBean.displayPassSummaryList}": java.lang.NullPointerException
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:119)
at com.sun.faces.facelets.component.UIRepeat.getValue(UIRepeat.java:314)
at com.sun.faces.facelets.component.UIRepeat.getDataModel(UIRepeat.java:256)
at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:507)
at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:557)
at com.sun.faces.facelets.component.UIRepeat.processDecodes(UIRepeat.java:861)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1258)....
调用 jsf 的一部分value="#{passesTestBean.displayPassSummaryList}"
是 100% 单独注销,PassesTestBean CDI 是请求范围。
所以当我点击注销按钮时,问题出在了某个地方。PassesTestBean 被无缘无故地调用,而不是因为 jsf 必须初始化(因为请求作用域)。它最终返回null。
现在请记住,这只发生在:example.com 的生产和所有页面的唯一主页。
我正在考虑编写一个仅用于注销的页面:只有一个注销按钮。