我正尝试将运行在Tomcat 8.5 Servlet 3.1容器中的旧Web应用程序从JSF 2.1.1-FCS升级到2.2.14。
Mojarra JSF最低要求(对于我想为最新版本的JSF,页面似乎不清晰)指出,除其他外,建议使用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容器上下文中更改此值的最佳方法是什么?
答案 0 :(得分: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>
这是最简单的解决方案,但是当我第一次读取the Weld documentation时,我并没有在该上下文参数名称与会话参数键或错误WELD-000321之间建立关联。
或通过编程设置
我还能够通过基于SO example for getting rid of the NonexistentConversationException的自定义ServletContextListener.contextInitialized方法以编程方式覆盖参数名称/上下文ID键。由于我使用的是Tomcat 8.5(Servlet 3.1),因此可以使用@WebListener或web.xml中的listener元素。我的web.xml网络应用程序版本是旧的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());
}
}