Java 提供多个端点的Cometd不能部署到同一路径[/Cometd]
我正在开发一个SpringMVC应用程序,试图将聊天功能与Cometd集成在一起。我得到一个错误,即不能在同一路径中部署多个端点 错误日志:Java 提供多个端点的Cometd不能部署到同一路径[/Cometd],java,spring,spring-mvc,websocket,comet,Java,Spring,Spring Mvc,Websocket,Comet,我正在开发一个SpringMVC应用程序,试图将聊天功能与Cometd集成在一起。我得到一个错误,即不能在同一路径中部署多个端点 错误日志: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cometDInitializer.Processor': Injection of autowired dependencies failed; nested exception
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cometDInitializer.Processor': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.cometd.bayeux.server.BayeuxServer com.journaldev.spring.chat.CometDInitializer$Processor.bayeuxServer; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bayeuxServer' defined in class path resource [com/journaldev/spring/chat/CometDInitializer.class]: Invocation of init method failed; nested exception is java.lang.RuntimeException: javax.websocket.DeploymentException: Multiple Endpoints may not be deployed to the same path [/cometd]
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
如果有人想要完整的错误日志
CometDiInitializer.java:
@Component
public class CometDInitializer implements ServletContextAware
{
private ServletContext servletContext;
@Bean(initMethod = "start", destroyMethod = "stop")
public BayeuxServer bayeuxServer()
{
BayeuxServerImpl bean = new BayeuxServerImpl();
bean.setTransports(new WebSocketTransport(bean), new JSONTransport(bean), new JSONPTransport(bean));
servletContext.setAttribute(BayeuxServer.ATTRIBUTE, bean);
bean.setOption(ServletContext.class.getName(), servletContext);
bean.setOption("ws.cometdURLMapping", "/cometd/*");
return bean;
}
public void setServletContext(ServletContext servletContext)
{
this.servletContext = servletContext;
}
@Component
public static class Processor implements DestructionAwareBeanPostProcessor
{
@Inject
private BayeuxServer bayeuxServer;
private ServerAnnotationProcessor processor;
@PostConstruct
private void init()
{
this.processor = new ServerAnnotationProcessor(bayeuxServer);
}
@PreDestroy
private void destroy()
{
}
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException
{
processor.processDependencies(bean);
processor.processConfigurations(bean);
processor.processCallbacks(bean);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException
{
return bean;
}
public void postProcessBeforeDestruction(Object bean, String name) throws BeansException
{
processor.deprocessCallbacks(bean);
}
}
}
HelloService.java:
@Named
@Singleton
@Service("helloService")
public class HelloService
{
@Inject
private BayeuxServer bayeux;
@Session
private ServerSession serverSession;
@PostConstruct
public void init()
{
}
@Listener("/service/hello")
public void processHello(ServerSession remote, ServerMessage message)
{
System.out.println("We recieved a helo msg");
Map<String, Object> input = message.getDataAsMap();
String name = (String)input.get("name");
Map<String, Object> output = new HashMap<>();
output.put("greeting", "Hello, " + name);
remote.deliver(serverSession, "/hello", output);
}
}
此异常是由您的设计引起的:
- 自注册后,BayeuxServer只能有一个实例
只能为一个实例调用bean.setOption("ws.cometdURLMapping", "/cometd/*");
- 有多个@Inject注释。因此,会生成多个实例。每个@Inject一个实例
@Bean(initMethod = "start", destroyMethod = "stop")
@Singleton
public BayeuxServer bayeuxServer()
现在只有一个BayeuxServer实例。所有@Inject都将获得相同的实例
这仅在实现支持JSR330的情况下有效。(对不起,春天不是!)
单身人士的硬编码方式:
private static BayeuxServer beanInstance;
public static synchronized BayeuxServer bayeuxServer()
{
if (beanInstance != null)
return beanInstance;
BayeuxServerImpl bean = new BayeuxServerImpl();
bean.setTransports(new WebSocketTransport(bean), new JSONTransport(bean), new JSONPTransport(bean));
servletContext.setAttribute(BayeuxServer.ATTRIBUTE, bean);
bean.setOption(ServletContext.class.getName(), servletContext);
bean.setOption("ws.cometdURLMapping", "/cometd/*");
beanInstance = bean;
return beanInstance;
}
这没有帮助,错误是一样的,下面是错误代码:我还尝试更改bean.setOptions第二个参数,但没有任何效果,我得到了相同的错误。
bean.setOption("ws.cometdURLMapping", "/cometd/*");
@Bean(initMethod = "start", destroyMethod = "stop")
@Singleton
public BayeuxServer bayeuxServer()
private static BayeuxServer beanInstance;
public static synchronized BayeuxServer bayeuxServer()
{
if (beanInstance != null)
return beanInstance;
BayeuxServerImpl bean = new BayeuxServerImpl();
bean.setTransports(new WebSocketTransport(bean), new JSONTransport(bean), new JSONPTransport(bean));
servletContext.setAttribute(BayeuxServer.ATTRIBUTE, bean);
bean.setOption(ServletContext.class.getName(), servletContext);
bean.setOption("ws.cometdURLMapping", "/cometd/*");
beanInstance = bean;
return beanInstance;
}