0

我正在尝试将旧 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 容器上下文中更改此值的最佳方法是什么?

4

1 回答 1

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());
    }

}
于 2019-05-20T20:14:48.233 回答