在 Glassfish 5 build 25 上的部署运行中的 Java EE 8/SE 8 Web 应用程序,无论是生产和开发,都使用 JSF 2.3。 用户创建帐户并登录。 有一个用于注销的"注销"按钮。
问题:"注销"按钮在网站上的任何地方都按预期工作。主页(example.com(和(example.com/home.xhtml(除外。我的本地计算机上不存在此问题。仅在生产中 (example.com(。
所以我有一个名为 : index.xhtml 的模板。 所有页面都使用它,包括主页.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;
}
}
}
用户登录和注销相当容易,直到我注意到单击主页(主页.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 并且只有所有页面的主页。
我正在考虑编写一个仅用于注销的页面:只有一个注销按钮。
检查空指针异常
getRequest().logout(); //here
getContext().getExternalContext().getSessionMap().remove("user");//here