I'm working on a shopping cart with JEE. My web application is made of one stateful session bean and two servlets with corresponding JSP pages. One servlet allows to add new items to the cart, the other allows to list the content of the cart.
The stateful session bean is supposed to save the state of the cart across pages, but the cart always appears to be empty. Could you help me to find out what's wrong with my code and explain why the current implementation is not sufficient ?
Servlet to add a new item to the cart:
package my.servlet;
import my.entity.BookEntity;
import my.entity.ItemEntity;
import my.session.BookBean;
import my.session.CartBean;
import javax.ejb.EJB;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/item")
public class ItemServlet extends HttpServlet {
@EJB
private BookBean bookBean;
@EJB
private CartBean cartBean;
@PersistenceContext(unitName = "book-pu")
private EntityManager bookManager;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
ServletContext ctx = getServletContext();
long book = Long.parseLong(request.getParameter("book"), 10);
RequestDispatcher dispatcher = ctx.getRequestDispatcher("/jsp/item.jsp");
request.setAttribute("book", bookManager.find(BookEntity.class, book));
request.setAttribute("item", null);
dispatcher.forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
ServletContext ctx = getServletContext();
int qty = Integer.parseInt(request.getParameter("qty"), 10);
long book = Long.parseLong(request.getParameter("book"), 10);
RequestDispatcher dispatcher = ctx.getRequestDispatcher("/jsp/item.jsp");
ItemEntity item = new ItemEntity(bookManager.find(BookEntity.class, book), qty);
request.setAttribute("book", bookManager.find(BookEntity.class, book));
request.setAttribute("item", item);
cartBean.addItem(item);
dispatcher.forward(request, response);
}
}
Servlet to list the content of the cart:
package my.servlet;
import my.session.CartBean;
import javax.ejb.EJB;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/cart")
public class CartServlet extends HttpServlet {
@EJB
private CartBean cartBean;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
ServletContext ctx = getServletContext();
RequestDispatcher dispatcher = ctx.getRequestDispatcher("/jsp/cart.jsp");
request.setAttribute("items", cartBean.getAllItems());
dispatcher.forward(request, response);
}
}
The Stateful Session Bean:
package my.session;
import java.util.ArrayList;
import java.util.Collection;
import javax.annotation.PostConstruct;
import javax.ejb.LocalBean;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.ejb.StatefulTimeout;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.concurrent.TimeUnit;
import my.entity.ItemEntity;
@LocalBean
@Stateful
@StatefulTimeout(unit = TimeUnit.MINUTES, value = 30)
public class CartBean implements CartItf {
private Collection<ItemEntity> items;
@PersistenceContext(unitName = "book-pu")
private EntityManager itemManager;
@PostConstruct
public void initialize() {
items = new ArrayList<ItemEntity>();
}
@Override
public void addItem(ItemEntity item)
{
items.add(item);
}
@Override
public Collection<ItemEntity> getAllItems()
{
return items;
}
@Remove
@Override
public void confirmOrder()
{
for (ItemEntity item : items) {
itemManager.persist(item);
}
}
}
you need to ensure to reuse the same stateful and not a new instance each time (each servlet). You have multiple options: