• SpringBoot使用JSR356 Websocket使用configurator = SpringConfigurator.class自动注入Spring IOC的bean报错: Failed to find the root WebApplicationContext. Was ContextLoaderListener not used?


    背景

    笔者在springboot中使用JSR356的Websocket注解,然后各种方式尝试注入Bean,大多失效。

    Spring MVC 4.x时代,推荐代码如下

    @ServerEndpoint(value = "/WSAPI/Equipment/JobCounterReport/{dispatchNo}",configurator = SpringConfigurator.class)

    经过多次尝试,还是错误了。如下

    java.lang.IllegalStateException: Failed to find the root WebApplicationContext. Was ContextLoaderListener not used?
        at org.springframework.web.socket.server.standard.SpringConfigurator.getEndpointInstance(SpringConfigurator.java:70) ~[spring-websocket-5.1.19.RELEASE.jar:5.1.19.RELEASE]
        at io.undertow.websockets.jsr.EndpointSessionHandler.onConnect(EndpointSessionHandler.java:73) [undertow-websockets-jsr-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.websockets.jsr.JsrWebSocketFilter$1.handleUpgrade(JsrWebSocketFilter.java:165) [undertow-websockets-jsr-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.server.protocol.http.HttpReadListener.exchangeComplete(HttpReadListener.java:389) [undertow-core-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.server.protocol.http.HttpServerConnection.exchangeComplete(HttpServerConnection.java:244) [undertow-core-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.server.HttpServerExchange.invokeExchangeCompleteListeners(HttpServerExchange.java:1279) [undertow-core-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.server.HttpServerExchange.terminateResponse(HttpServerExchange.java:1563) [undertow-core-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.server.Connectors.terminateResponse(Connectors.java:159) [undertow-core-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.server.protocol.http.HttpTransferEncoding$3.handleEvent(HttpTransferEncoding.java:199) [undertow-core-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.server.protocol.http.HttpTransferEncoding$3.handleEvent(HttpTransferEncoding.java:197) [undertow-core-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.conduits.HeadStreamSinkConduit.exitFlush(HeadStreamSinkConduit.java:192) [undertow-core-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.conduits.HeadStreamSinkConduit.flush(HeadStreamSinkConduit.java:133) [undertow-core-2.0.32.Final.jar:2.0.32.Final]
        at org.xnio.conduits.ConduitStreamSinkChannel.flush(ConduitStreamSinkChannel.java:162) [xnio-api-3.3.8.Final.jar:3.3.8.Final]
        at io.undertow.channels.DetachableStreamSinkChannel.flush(DetachableStreamSinkChannel.java:119) [undertow-core-2.0.32.Final.jar:2.0.32.Final]
        at org.xnio.channels.Channels.flushBlocking(Channels.java:63) [xnio-api-3.3.8.Final.jar:3.3.8.Final]
        at io.undertow.servlet.spec.ServletOutputStreamImpl.close(ServletOutputStreamImpl.java:619) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.servlet.spec.HttpServletResponseImpl.closeStreamAndWriter(HttpServletResponseImpl.java:534) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.servlet.spec.HttpServletResponseImpl.responseDone(HttpServletResponseImpl.java:623) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:328) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99) [undertow-servlet-2.0.32.Final.jar:2.0.32.Final]
        at io.undertow.server.Connectors.executeRootHandler(Connectors.java:376) [undertow-core-2.0.32.Final.jar:2.0.32.Final]

    解决方法1:静态注入

    @Component
    @Slf4j
    @ServerEndpoint(value = "/WSAPI/Equipment/JobCounterReport/{dispatchNo}")
    public class WebSocketServer implements DynamicSQLCondition {
    
    public static ProcessOrderInfoMapper processOrderInfoMapper;
    
    @Autowired
    public void setProcessOrderInfoMapper(final ProcessOrderInfoMapper processOrderInfoMapper) {
        WebSocketServer.processOrderInfoMapper = processOrderInfoMapper;
    }
    
    }

    解决方案2:自定义configurator 

    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    import javax.websocket.server.ServerEndpointConfig;
    
    /**
     * @author: passedbylove
     * @date: Created by  2022/3/19 22:20
     * @version: 1.0.0
     */
    public class CustomSpringConfigurator extends ServerEndpointConfig.Configurator implements ApplicationContextAware {
    
        private static volatile BeanFactory context;
    
        public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
            return context.getBean(endpointClass);
        }
    
        @Override
        public void setApplicationContext(final ApplicationContext context) throws BeansException {
            this.context = context;
        }
    @Configuration
    public class WebSocketConfiguration {
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    
        @Bean
        public CustomSpringConfigurator customSpringConfigurator()
        {
            return new CustomSpringConfigurator();
        }
    }

    然后Websocket配置如下

    @Component
    @Slf4j
    @ServerEndpoint(value = "/WSAPI/Equipment/JobCounterReport/{dispatchNo}",configurator = CustomSpringConfigurator.class)
    public class WebSocketServer implements DynamicSQLCondition {
    
    
        @Autowired
        private ProcessOrderInfoMapper processOrderInfoMapper;
    }

    方法来自网络,版权归原作者所有

    java - Springboot @ServerEndPoint "Failed to find the root WebApplicationContext." - IT工具网 (coder.work)

    java - Springboot @ServerEndPoint "Failed to find the root WebApplicationContext." - Stack Overflow

  • 相关阅读:
    2015.07.20MapReducer源码解析(笔记)
    Hive(笔记)
    HDFS入门(1)
    Zookepper(2015.08.16笔记)
    USB_ModeSwitch 介绍(转)
    Perl 模块 Getopt::Std 和 Getopt::Long
    在linux下设置开机自动启动程序的方法
    gcc Makefile 入门
    Linuxexec函数族及system函数
    signal(SIGHUP, SIG_IGN)的含义
  • 原文地址:https://www.cnblogs.com/passedbylove/p/16028415.html
Copyright © 2020-2023  润新知