背景

笔者在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

posted on 2022-03-19 22:43  你不知道的浪漫  阅读(506)  评论(0编辑  收藏  举报