我正在使用Primefaces标记库开发一个应用程序。
到目前为止,我已经从他们的官方网站上复制了一些示例,除了使用RequestContext.getCurrentInstance()方法的任何内容之外,所有示例似乎都有效。它每次都返回null,导致Tomcat抛出NullPointer异常或永久挂起,永远不会返回任何内容。
这是我的代码(它挂起的情况):
GlobalCounterBean.java
package org.primefaces.examples.view;
import java.io.Serializable;
import org.primefaces.context.RequestContext;
public class GlobalCounterBean implements Serializable{
private int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public synchronized void increment() {
count++;
System.out.println("aaaa");
RequestContext.getCurrentInstance().push("counter", count);
}
}
test.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<p:spinner />
<h:form>
<h:outputText value="#{globalCounter.count}" styleClass="ui-widget display" />
<br />
<p:commandButton value="Click" actionListener="#{globalCounter.increment}" />
</h:form>
<p:push onmessage="handleMessage" channel="counter" />
<script type="text/javascript">
function handleMessage(evt, data) {
$('.display').html(data);
}
</script>
</h:body>
</html>
以下是返回null的情况下的代码(所有文件都在同一个项目中):
ChatController.java:
package org.primefaces.examples.view;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.context.RequestContext;
public class ChatController implements Serializable {
private final static String CHANNEL = "chat";
private String message;
private String username;
private boolean loggedIn;
private Set<String> users = new HashSet<String>();
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public boolean isLoggedIn() {
return loggedIn;
}
public void setLoggedIn(boolean loggedIn) {
this.loggedIn = loggedIn;
}
public void send() {
RequestContext.getCurrentInstance().push(CHANNEL, username + ": "+ message);
message = null;
}
public void login() {
RequestContext requestContext = RequestContext.getCurrentInstance();
if(users.contains(username)) {
loggedIn = false;
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Username taken", "Try with another username."));
requestContext.addPartialUpdateTarget("growl");
}
else {
users.add(username);
loggedIn = true;
requestContext.push(CHANNEL, username + " joined the channel.");
}
}
public void disconnect() {
RequestContext.getCurrentInstance().push(CHANNEL, username + " has left the channel.");
loggedIn = false;
username = null;
}
}
chat.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>
</head>
<body>
<f:view>
<p:growl id="growl" showDetail="true" />
<h:form>
<p:fieldset id="container" legend="PrimeChat">
<h:panelGroup rendered="#{chatController.loggedIn}" >
<p:outputPanel layout="block" style="width:600px;height:200px;overflow:auto"
styleClass="chatroom" />
<p:spinner />
<p:separator />
<p:inputText value="#{chatController.message}" styleClass="messageInput" />
<p:spacer width="5" />
<p:commandButton value="Send" actionListener="#{chatController.send}" global="false" oncomplete="$('.messageInput').val('').focus()"/>
<p:spacer width="5" />
<p:commandButton value="Disconnect" actionListener="#{chatController.disconnect}" global="false"
oncomplete="chatAgent.close()" update="container" />
</h:panelGroup>
<h:panelGroup rendered="#{not chatController.loggedIn}" >
Username: <p:inputText value="#{chatController.username}" />
<p:spacer width="5" />
<p:commandButton value="Login" actionListener="#{chatController.login}" update="container"
icon="ui-icon-person"/>
</h:panelGroup>
</p:fieldset>
</h:form>
<p:push onmessage="handleMessage" channel="chat" widgetVar="chatAgent" />
<script type="text/javascript">
function handleMessage(evt, data) {
var chatContent = $('.chatContent');
chatContent.append(data + '<br />');
//keep scroll
chatContent.scrollTop(chatContent.height());
}
</script>
<script type="text/javascript">
function handleComplete(xhr, status, args) {
if(args.validationFailed) {
PrimeFaces.debug("Validation Failed");
}
else {
PrimeFaces.debug("Save:" + args.saved);
PrimeFaces.debug("FirstName: " + args.user.firstname + ", Lastname: " + args.user.lastname);
}
}
</script>
</f:view>
</body>
</html>
faces-config.xml中:
<?xml version="1.0" encoding="utf-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<managed-bean eager="true">
<managed-bean-name>chatController</managed-bean-name>
<managed-bean-class>org.primefaces.examples.view.ChatController</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>globalCounter</managed-bean-name>
<managed-bean-class>org.primefaces.examples.view.GlobalCounterBean</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
<!--
No ManagedBean declarations here as we are using @ManagedBean Annotations.
-->
</faces-config>
的web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" >
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
这是tomcat控制台中抛出的异常:
2012-05-27 19:16:25 com.sun.faces.context.ExceptionHandlerImpl log
SEVERE: JSF1073: javax.faces.event.AbortProcessingException caught during processing of INVOKE_APPLICATION 5 : UIComponent-ClientId=j_idt2:j_idt16, Message=java.lang.NullPointerException
2012-05-27 19:16:25 com.sun.faces.context.ExceptionHandlerImpl log
SEVERE: java.lang.NullPointerException
javax.faces.event.AbortProcessingException: java.lang.NullPointerException
at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:178)
at javax.faces.event.ActionEvent.processListener(ActionEvent.java:84)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:773)
at javax.faces.component.UICommand.broadcast(UICommand.java:296)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:781)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1246)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:77)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:680)
Caused by: java.lang.NullPointerException
at org.primefaces.examples.view.ChatController.login(ChatController.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.el.parser.AstValue.invoke(AstValue.java:191)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:149)
... 21 more
答案 0 :(得分:2)
您的web.xml
缺少PrimeFaces推送设置的“网址配置”部分。
正如我在previous question上的回答中所提到的,PrimeFaces Push的安装细节在PrimeFaces User's Guide的第6章中列出。以下是您缺少的步骤的相关摘录:
6.1设置
推送服务器
PrimeFaces Push使用servlet作为调度程序。此servlet应与JSF应用程序位于不同的应用程序中,目前只能部署在jetty服务器上。
<servlet> <servlet-name>Push Servlet</servlet-name> <servlet-class>org.primefaces.push.PushServlet</servlet-class> <load-on-startup>1</load-on-startup> <init-param> <param-name>channels</param-name> <param-value>chat,counter</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Push Servlet</servlet-name> <url-pattern>/prime-push/*</url-pattern> </servlet-mapping>
渠道配置定义推送服务器可以发布到的主题名称。
网址配置
JSF应用程序需要定义推送服务器URL以发送消息。
<context-param> <param-name>primefaces.PUSH_SERVER_URL</param-name> <param-value>ws://url_to_push_server</param-value> </context-param>