Search code examples
servletscdiconversation-scope

ConversationScoped bean injected in servlet behaves like a RequestScoped bean


My intention is just to invoke a conversationscoped bean by a servlet. The bean itself should increase its property ticketnumber up to 4.

This is the servlet:

@WebServlet
public class ConversationServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Inject
    private GreetingTicket ticket;


    @Override
    public void init() throws ServletException {
        System.out.println("Init");
        ticket.beginConversation();
    }

    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        System.out.println("DoGet");
        PrintWriter writer = response.getWriter();
        response.setContentType("text/html");

        ticket.addTicketNumber();

        System.out.println(ticket.getTicketNumber());

        writer.println("<h1>" + ticket.getTicketNumber() + "</h1>");

        if (ticket.getTicketNumber() == 4) {
            System.out.println("END!");
            ticket.endConversation();
        }

        writer.flush();
        writer.close();

    }
}

The class GreetingTicket is the conversationscoped CDI-Bean:

@ConversationScoped
public class GreetingTicket implements Serializable {

    @Inject
    Conversation conversation;

    private static final long serialVersionUID = 1L;
    private int ticketNumber;

    public GreetingTicket() {
        System.out.println("greeting Ticket");
    }

    public int getTicketNumber() {
        return ticketNumber;
    }

    public void setTicketNumber(int ticketNumber) {
        this.ticketNumber = ticketNumber;
    }

    public void addTicketNumber() {
        ticketNumber++;
        System.out.println("TicketNumber increased to "+ticketNumber);
    }

    public void beginConversation() {
        if (conversation.isTransient()) {
            System.out.println("Conversation Begin!");
            conversation.begin();
        }
    }

    public void endConversation() {
        if (!(conversation.isTransient())) {
            System.out.println("Conversation End!");
            conversation.end();
        }
    }
}

The result is now that the ticketnumber of GreetingTicket always only counts to 1by every request - why?


Solution

  • @John Ament is right in his comment. You need to pass cid parameter from client to the server.

    Because with following code you are always starting a new conversation:

    @Override
    public void init() throws ServletException {
        System.out.println("Init");
        ticket.beginConversation();
    }
    

    You need to pass request parameter named cid, something like:

    @WebServlet
    public class ConversationServlet extends HttpServlet {
    
        @Inject
        private GreetingTicket ticket;
    
        @Override
        protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
    
           final String cid = request.getParameter("cid"); 
           // TODO: pass above cid to the conversation
    
           // ...
        }
    }