Using Java API for WebSocket (JSR-356) with Spring Download

I am new to Spring (and asking questions about stackoverflow).

I would like to start the embedded (Tomcat) server through Spring Boot and register the WebSocket JSR-356 endpoint.

This is the main method:

@ComponentScan @EnableAutoConfiguration public class Server { public static void main(String[] args) { SpringApplication.run(Server.class, args); } } 

This is what the configuration looks like:

 @Configuration public class EndpointConfig { @Bean public EchoEndpoint echoEndpoint() { return new EchoEndpoint(); } @Bean public ServerEndpointExporter endpointExporter() { return new ServerEndpointExporter(); } } 

EchoEndpoint implementation is straightforward:

 @ServerEndpoint(value = "/echo", configurator = SpringConfigurator.class) public class EchoEndpoint { @OnMessage public void handleMessage(Session session, String message) throws IOException { session.getBasicRemote().sendText("echo: " + message); } } 

In the second part, I followed this blog post: https://spring.io/blog/2013/05/23/spring-framework-4-0-m1-websocket-support .

However, when I launch the application, I get:

 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 

Also, the exception is thrown by a NullPointerException in ServerEndpointExporter because the getServletContext method in applicationContext returns still null at this point.

Can someone with a better understanding of Spring help me? Thanks!

+6
source share
1 answer

ServerEndpointExporter makes some assumptions about the application context life cycle that fails when you use Spring Boot. In particular, it is assumed that, when calling setApplicationContext calling getServletContext ApplicationContext return a nonzero value.

You can work around the problem by replacing:

 @Bean public ServerEndpointExporter endpointExporter() { return new ServerEndpointExporter(); } 

WITH

 @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); } } }; } 

Rejects processing until a servlet context is available.

Refresh . You may like to watch SPR-12109 . After fixing the workaround described above, it is no longer required.

+6
source

Source: https://habr.com/ru/post/974044/


All Articles