java - 从 WebListener 中的 ServerContainer 中删除端点

标签 java spring tomcat dependency-injection jira

在我的 JIRA 插件中,我创建了一个 WebListener,它将一个 websocket 端点添加到 SeverContainer。

问题是,当我更改我的插件并将其上传到 JIRA 时,新代码没有执行。

这是因为没有再次部署端点。我收到以下异常:多个端点可能不会部署到同一路径

我的网络监听器:

@WebListener
public class MyListener implements ServletContextListener {

    private static final Logger LOG = LoggerFactory.getLogger(MyListener.class);

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        final ServerContainer serverContainer = (ServerContainer) servletContextEvent.getServletContext()
                .getAttribute("javax.websocket.server.ServerContainer");
        try {
            serverContainer.addEndpoint(MyWebsocket.class); //Generates exception when the plug-in is updated
        } catch (DeploymentException e) {
            LOG.error("Error adding endpoint to the servercontainer: " + e.getMessage());
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        LOG.error("CONTEXT DESTROYED!");
    }
}

我的网络套接字:

@ServerEndpoint(value = "/websocket/{myPathParam}")
public class MyWebsocket {

    private static final Logger LOG = LoggerFactory.getLogger(MyWebsocket.class);

    @OnOpen
    public void onOpen(Session session, @PathParam("myPathParam") String myPathParam) {
        LOG.error("OnOpen");
    }

    @OnClose
    public void onClose(Session session, @PathParam("myPathParam") String myPathParam) {
        LOG.error("OnClose");
    }

    @OnMessage
    public void onMessage(String message, Session session, @PathParam("myPathParam") String myPathParam) {
        LOG.error("OnMessage: " + message);
    }
}

有没有办法从服务器容器中删除端点,以便再次部署它?

最佳答案

在规范中,我没有找到任何方法来停用 websocket。这同样适用于 ServletContextListeners。它们只能被添加。因此,您需要一个解决方法。

我建议您不要替换 MyEndpoint.class,而是将其设为将调用实现的代理。因此,端点不需要重新注册,新代理类在部署时调用新代码。

因此,您可以安全地忽略代码中的 DeploymentException,因为您更改了 MyWebsocket.class,如下所示:

@ServerEndpoint(value = "/websocket/{myPathParam}")
public class MyWebsocket {

    private static final Logger LOG = LoggerFactory.getLogger(MyWebsocket.class);

    @OnOpen
    public void onOpen(Session session, @PathParam("myPathParam") String myPathParam) {
        LOG.error("OnOpen");
        WebSocketImpl impl = ImplementationFactory.get(MyWebsocket.class);
        impl.onOpen(session, myPathParam);
    }

    @OnClose
    public void onClose(Session session, @PathParam("myPathParam") String myPathParam) {
        LOG.error("OnClose");
        WebSocketImpl impl = ImplementationFactory.get(MyWebsocket.class);
        impl.onClose(session, myPathParam);
    }

    @OnMessage
    public void onMessage(String message, Session session, @PathParam("myPathParam") String myPathParam) {
        LOG.error("OnMessage: " + message);
        WebSocketImpl impl = ImplementationFactory.get(MyWebsocket.class);
        impl.onMessage(message, session, myPathParam);
    }
}

我知道,这不会真正回答您的问题,但它是解决缺少删除选项的解决方案。

此解决方法存在一个问题:它将修复您的界面,您无法在新版本的插件中添加参数。

要启用此功能,您可以通过添加另一个上下文监听器来添加另一个 websocket(随机选择了 V7):

@WebListener
public class MyListener_V7 implements ServletContextListener {

private static final Logger LOG = LoggerFactory.getLogger(MyListener_V7.class);

@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
    final ServerContainer serverContainer = (ServerContainer) servletContextEvent.getServletContext()
            .getAttribute("javax.websocket.server.ServerContainer");
    try {
        serverContainer.addEndpoint(MyWebsocket_V7.class); //Generates exception when the plug-in is updated
    } catch (DeploymentException e) {
        LOG.error("Error adding endpoint to the servercontainer: " + e.getMessage());
    }
}

@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
    LOG.error("CONTEXT DESTROYED!");
}
}

@ServerEndpoint(value = "/websocket_V7/{myPathParam}")
public class MyWebsocket_V7 {

private static final Logger LOG = LoggerFactory.getLogger(MyWebsocket.class);

这将在 JIRA 实例中散布端点,直到重新启动。但是,如果混合使用这两种建议,您只会每隔一段时间添加一个新端点。

关于java - 从 WebListener 中的 ServerContainer 中删除端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33611866/

相关文章:

java - 在 spring-boot 上执行 optaplanner 期间出现奇怪的警告

Java - 为什么 hibernate 会检测到脏对象,尽管它已经保存了?

java - 在运行时更改 spring 数据源设置

java - 处理 Spring/Tomcat 初始化失败

java - 如何在本地 TomCat 服务器托管的 JSF 应用程序中使用在外部 JAR 中声明的接口(interface)

java - 如何确认消息传送到 Amazon SQS 队列?

java - 使用 pdfbox 旋转

java - 打印列表中除最后一个值之外的所有值。

java - 如何登录我的新 Spring Boot 应用程序?

unit-testing - 在没有启动嵌入式 tomcat 的情况下运行 grails 功能测试