Search code examples
javacdiweld

Reattach to conversation with Java CDI Weld


I want to join an existing conversation scope.

I start the conversation with:

conversation.begin(packageId);

I got close with using the following which seems to work:

@Inject @Http CoversationContext context;

context.activate(packageId);

However I'm seeing a warning in the log which suggests I'm not getting it right.

WARN: WELD-000335: Conversation context is already active, most likely it was not cleaned up properly during previous request processing: HttpServletRequestImpl [ POST /path/to/url ]

I'm also happy if there is an alternative way to just drop the conversation and recreate (so long as I can continue using the same custom conversation ID) I'm trying to avoid the user reloading the page multiple times filling up memory with duplicates of the same package data.

I also considered using a @SessionScoped bean but I thought if I can set the package ID to be the conversation ID then I can avoid the need to manage a @SessionScoped bean.


Solution

  • As long as the cid parameter is in request, and the conversation is long-running (since you did conversation.begin(packageId)) then there is no need to join a conversation context, it is already active in current request.

    What you need to do however is to include the cid in every request form or in url parameters through:

    e.g.

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

    or

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

    Note that the conversation must be long-running by explicitly starting it as conversation.begin(id)

    Also:

    At the end of your step processing, you need to explicitly call conversation.end() otherwise the conversation scoped beans will be destroyed only at the end of the session context

    For book marking, then you need to include the cid parameter or any logical mapping in the path, and then use a filter to forward with the cid parameter:

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