首页 > 解决方案 > 如何在 Tomcat 8.5/Servlet 3.1 上初始化 Weld 3.0 cid setParameterName

问题描述

我正在尝试将旧 Web 应用程序从 JSF 2.1.1-FCS 升级到在 Tomcat 8.5 Servlet 3.1 容器中运行的 2.2.14。

Mojarra JSF 最低要求(我猜对于最新版本,该页面似乎不清楚)除其他外说 CDI 1.2 需要 CDI 1.2 推荐 2.0。

我添加了 cd-api-2.0 和weld-servlet-shaded-3.0.0.Final 以及其他依赖项。在我测试一些我们已经使用了很长时间的 URL 之前,一切似乎都有效。我们的应用程序一直在使用cid参数。Weld 使用相同的参数来跟踪对话。结果我们得到了WELD-000321: No conversation found to restore for id错误。

我想org.jboss.weld.context.http.HttpConversationContext.setParameterName(String cid)尽早调用以修改此 Web 应用程序的值。

在 Tomcat 8.5 提供的 Servlet 3.1 容器上下文中更改此值的最佳方法是什么?

标签: cdijsf-2.2tomcat8.5servlet-3.1

解决方案


在 web.xml 中初始化 WELD_CONTEXT_ID_KEY

使用 web.xml 上下文参数 WELD_CONTEXT_ID_KEY 允许我将 Weld CDI 对话参数键名称从 cid 覆盖为我选择的值,这样我就可以在升级的应用程序中保留 cid 的旧用法并避免 WELD-000321 错误。

<context-param>
    <param-name>WELD_CONTEXT_ID_KEY</param-name>
    <param-value>customValue</param-value>
</context-param>

这是最简单的解决方案,但我在第一次阅读Weld 文档时没有在该上下文参数名称和对话参数键或错误 WELD-000321 之间建立关联。

或以编程方式设置

我还能够从基于SO 示例的自定义 ServletContextListener.contextInitialized 方法以编程方式覆盖参数名称/上下文 ID 键,以摆脱 NonexistentConversationException。由于我使用的是 Tomcat 8.5(Servlet 3.1),因此我能够使用 @WebListener 或 web.xml 中的侦听器元素。我的 web.xml web-app 版本是旧的 2.5 还是更新到 3.1 似乎并不重要。

package ssce;

import java.util.UUID;
import javax.inject.Inject;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.jboss.weld.context.http.HttpConversationContext;

@WebListener
public class MyServletContextListener implements ServletContextListener {

    @Inject
    private HttpConversationContext conversationContext;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        hideConversationScope();
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }


    /**
     * "Hide" conversation scope by replacing its default "cid" parameter name
     * by something unpredictable.
     */
    private void hideConversationScope() {
        conversationContext.setParameterName(UUID.randomUUID().toString());
    }

}

推荐阅读