jsf - NullPointerException 使用 JSF 2.3 websocket 使用 JSF 导航
问题描述
我使用 primefaces 菜单进行了一些简单的导航。但是我在两个页面上都有 jsf websockets。在页面之间导航时,这会导致 NullPointerException。当导航到投资组合时,如果投资组合页面中存在 websocket,则在尝试导航到它并返回到股票页面时会返回 NullPointerException。如果我从 Portfolio 页面中删除所有 websocket,则导航类型会起作用 - 第一次单击会导致以下异常,但第二次会起作用。如果我从两个页面中删除所有 websocket,导航将毫无问题,但显然我需要 websocket 来实现页面功能。
编辑:我现在制作了一个最小的可重现示例并更改了下面的代码。请注意,包含 h:commandLink 并且在选择 page2 时它们也会导致相同的问题。
java.lang.NullPointerException
at com.sun.faces.push.WebsocketFacesListener.processEvent(WebsocketFacesListener.java:118)
at javax.faces.event.SystemEvent.processListener(SystemEvent.java:147)
at javax.faces.event.ComponentSystemEvent.processListener(ComponentSystemEvent.java:134)
at com.sun.faces.application.ApplicationImpl.processListenersAccountingForAdds(ApplicationImpl.java:2340)
at com.sun.faces.application.ApplicationImpl.invokeViewListenersFor(ApplicationImpl.java:2158)
at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:337)
at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:292)
at javax.faces.application.ApplicationWrapper.publishEvent(ApplicationWrapper.java:748)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:113)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:223)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:671)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1580)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:338)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.glassfish.tyrus.servlet.TyrusServletFilter.doFilter(TyrusServletFilter.java:305)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:250)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:652)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:591)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:463)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:168)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:242)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
at java.lang.Thread.run(Thread.java:748)
这是我的菜单页面:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:view>
<h:head>
</h:head>
<h:body>
<div class="column side">
<h2>Side</h2>
<h:form>
<h:commandLink value="Page1" actionListener="#{menuViewTest.selectPageOne}" />
<h:commandLink value="Page2" actionListener="#{menuViewTest.selectPageTwo}" />
</h:form>
</div>
<div class="column middle">
<h2>Middle</h2>
<ui:include src="#{menuViewTest.view}">
</ui:include>
</div>
</h:body>
</f:view>
</html>
MenuTest 的支持 bean:
@Named("menuViewTest")
@SessionScoped
public class MenuViewTest implements Serializable {
private static final long serialVersionUID = -1015364935820045523L;
private String view;
public void selectPageOne() {
setView("page1.xhtml");
}
public void selectPageTwo() {
setView("page2.xhtml");
}
public String getView() {
return view;
}
public void setView(String view) {
this.view = view;
}
public String getSelectPageOne(){
return "page1.xhtml";
}
public String getSelectPageTwo(){
return "page2.xhtml";
}
}
第 1 页:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<script type="text/javascript">
function notifyListener(message, channel, event) {
console.log("notifyListener message: " + message);
console.log("notifyListener channel: " + channel);
console.log("notifyListener event: " + event);
}
</script>
<h2>Page 1</h2>
<f:websocket channel="notify" onmessage="notifyListener" />
</ui:composition>
第2页:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<script type="text/javascript">
function notifyListener(message, channel, event) {
console.log("notifyListener message: " + message);
console.log("notifyListener channel: " + channel);
console.log("notifyListener event: " + event);
}
</script>
<h2>Page 2</h2>
<f:websocket channel="notify2" onmessage="notifyListener" />
</ui:composition>
解决方案
通过使用 mojarra 2.3.9 升级到 Glassfish (5.1.0) JSF 版本 2.3 的最新稳定版本来修复 websocket 异常。
推荐阅读
- ios - 用于从应用商店检索 iOS 总评分的 API?
- url - ExtJS 在标签字段中缺少 ServerProxy 的 url
- javascript - /x|y|z/ 的含义
- python - 如何运行影响我的变量且不会破坏我的代码的 while 循环?
- python-3.x - OSX PyShark:RuntimeWarning:从未等待协程“wait_for”
- clang - 如何识别 Clang QualType 是函数指针?
- mongodb - docker-compose 在 mognodb 中创建用户
- python - 如何在 python 中将多个图像打包到一个图像或 numpy 数组中?
- ios - TableViewController 和 ViewController 之间的委托
- javascript - Easyautocomplete + Vue.js - 如何通过点击更新存储的变量?