重新加入与Java CDI Weld的对话

时间:2018-08-11 20:51:31

标签: java cdi weld

我想加入现有的对话范围。

我通过以下方式开始对话:

conversation.begin(packageId);

我很接近使用以下似乎有效的方法:

@Inject @Http CoversationContext context;

context.activate(packageId);

但是,我在日志中看到一条警告,提示我没有正确执行操作。

  

警告:WELD-000335:对话上下文已经处于活动状态,很可能   在先前的请求处理期间未正确清理它:   HttpServletRequestImpl [POST / path / to / url]

如果有另一种方法可以放下对话并重新创建(只要我可以继续使用相同的自定义对话ID),我也很高兴,我试图避免用户多次重新加载页面而将其填满具有相同包装数据重复项的内存。

我也考虑过使用@SessionScoped bean,但是我想如果可以将程序包ID设置为会话ID,那么就可以避免管理@SessionScoped bean了。

1 个答案:

答案 0 :(得分:0)

只要请求cid且对话为long-running(因为您进行了conversation.begin(packageId)),就不需要加入对话上下文,它已经在当前请求中处于活动状态。

但是,您需要做的是通过以下方式在每个请求形式或url参数中包含cid

例如

<h:link> <f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/> </h:link>

<h:form> <f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/> /h:form>

  
    

请注意,会话必须通过将其显式启动为session.begin(id)

来长时间运行。   

也:

  
    

在步骤处理的最后,您需要显式调用conversation.end(),否则,只有在会话上下文结束时,才会破坏对话范围的Bean

  

要进行书签标记,则需要在路径中包含cid参数或任何逻辑映射,然后使用过滤器将cid参数转发:

@WebFilter(urlPatterns = "/*")
public class CidFilter implements Filter {

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        String cid = extractCidParameterIfAny(request);
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        if (cid != null) {
            String forwardUrl = buildForwardUrlWithCidParameter(cid);
            HttpServletRequest wrapper = new CidHttpServletRequest(httpRequest);
            httpRequest.getRequestDispatcher(forwardUrl).forward(wrapper, response);
        } else {
            chain.doFilter(request, response);
        }
    }

}