我是Spring的新手(正在问stackoverflow的问题)。
我想通过Spring Boot启动嵌入式(Tomcat)服务器,并向其注册JSR-356 WebSocket端点。
这是主要方法:
@ComponentScan @EnableAutoConfiguration public class Server { public static void main(String[] args) { SpringApplication.run(Server.class, args); } }
这是配置的样子:
@Configuration public class EndpointConfig { @Bean public EchoEndpoint echoEndpoint() { return new EchoEndpoint(); } @Bean public ServerEndpointExporter endpointExporter() { return new ServerEndpointExporter(); } }
该EchoEndpoint实施是直截了当:
EchoEndpoint
@ServerEndpoint(value = "/echo", configurator = SpringConfigurator.class) public class EchoEndpoint { @OnMessage public void handleMessage(Session session, String message) throws IOException { session.getBasicRemote().sendText("echo: " + message); } }
对于第二部分,我关注了此博客文章:https : //spring.io/blog/2013/05/23/spring- framework-4-0-m1-websocket-support。
但是,当我运行该应用程序时,我得到:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'endpointExporter' defined in class path resource [hello/EndpointConfig.class]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Failed to get javax.websocket.server.ServerContainer via ServletContext attribute
该异常进一步由NullPointerExceptionin 引起ServerEndpointExporter,因为getServletContext此时applicationContext返回的方法仍在null。
NullPointerException
ServerEndpointExporter
getServletContext
applicationContext
null
可以更好地了解Spring的人可以帮助我吗?谢谢!
ServerEndpointExporter对应用程序上下文的生命周期做出一些假设,而这些假设在使用Spring Boot时并不成立。具体来说,假设在setApplicationContext调用when时,调用getServletContext该方法ApplicationContext将返回非null值。
setApplicationContext
ApplicationContext
您可以通过以下方法解决此问题:
@Bean public ServerEndpointExporter endpointExporter() { return new ServerEndpointExporter(); }
带有:
@Bean public ServletContextAware endpointExporterInitializer(final ApplicationContext applicationContext) { return new ServletContextAware() { @Override public void setServletContext(ServletContext servletContext) { ServerEndpointExporter serverEndpointExporter = new ServerEndpointExporter(); serverEndpointExporter.setApplicationContext(applicationContext); try { serverEndpointExporter.afterPropertiesSet(); } catch (Exception e) { throw new RuntimeException(e); } } }; }
这将延迟处理,直到Servlet上下文可用为止。
更新 :您可能喜欢看SPR-12109。一旦修复,就不再需要上述解决方法。