使用带有Spring Boot的Java API for WebSocket(JSR-356) [英] Using Java API for WebSocket (JSR-356) with Spring Boot

查看:161
本文介绍了使用带有Spring Boot的Java API for WebSocket(JSR-356)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Spring的新手(并在stackoverflow上提问)。

I'm new to Spring (and asking questions on stackoverflow).

我想通过Spring Boot启动嵌入式(Tomcat)服务器并向其注册JSR-356 WebSocket端点。

I'd like to start an embedded (Tomcat) server via Spring Boot and register a JSR-356 WebSocket endpoint to it.

这是主要方法:

@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 实现很简单:

@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

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

然而,当我运行应用程序时,我得到了:

However, when I run 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

该异常还是由 ServerEndpointExporter 中的 NullPointerException 引起的,因为 getServletContext applicationContext 上的c $ c>方法此时仍然返回 null

The exception is further caused by a NullPointerException in ServerEndpointExporter, because the getServletContext method on the applicationContext returns still null at this point.

对Spring有更好理解的人可以帮助我吗?谢谢!

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

推荐答案

ServerEndpointExporter 对应用程序的生命周期做出一些假设当您使用Spring Boot时,上下文不成立。具体来说,假设当调用 setApplicationContext 时,在 ApplicationContext上调用 getServletContext 将返回非空值。

ServerEndpointExporter makes some assumptions about the lifecycle of an application context that don't hold true when you're using Spring Boot. Specifically, it's assuming that when setApplicationContext is called, calling getServletContext on that ApplicationContext will return a non-null value.

您可以通过替换来解决此问题:

You can work around the problem by replacing:

@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上下文可用。

This defers the processing until the servlet context is available.

更新:您可能希望观看 SPR-12109 。一旦修复,就不再需要上述解决方法。

Update: You may like to watch SPR-12109. Once it's fixed the workaround described above should no longer be necessary.

这篇关于使用带有Spring Boot的Java API for WebSocket(JSR-356)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆