I am using JSPs and servlets to create a working shopping cart wherein the user can add and remove an item from their cart. These items will be displayed on a table. The code works fine for these features except for a bug that when they add an item with the same ID, it just adds a new row instead of updating the existing record.
Result I get:
| Item ID | Item Name | Qty | Action |
|---------------|------------------|------------------|------------------|
| 1 | Bag | 1 | Remove Item |
| 2 | Pencil | 5 | Remove Item |
| 1 | Bag | 3 | Remove Item |
Expected Result:
| Item ID | Item Name | Qty | Action |
|---------------|------------------|------------------|------------------|
| 1 | Bag | 4 | Remove Item |
| 2 | Pencil | 5 | Remove Item |
JSP: index.jsp
<body>
<h1>Cart</h1>
<form action="addToCart" method="POST">
<input type="text" name="id" placeholder="Item ID"/><br>
<input type="text" name="itemName" placeholder="Item Name"/><br>
<input type="text" name="qty" placeholder="Qty"/><br>
<input type="submit" name="submit" value="Add"/><br>
</form>
<table>
<th>Item ID</th>
<th>Item Name</th>
<th>Qty</th>
<th>Action</th>
<%
ArrayList<Item> arrayList = new ArrayList<Item>();
if (request.getServletContext().getAttribute("cartItemList") != null) {
arrayList = (ArrayList<Item>) request.getServletContext().getAttribute("cartItemList");
if(!arrayList.isEmpty())
{
for (Item item : arrayList)
{
%>
<tr>
<td><%= item.getItemId() %></td>
<td><%= item.getItemName() %></td>
<td><%= item.getQty() %></td>
<td><form method="POST" action="removeFromCart">
<input type="text" name="id" value="<%= item.getItemId() %>" hidden/>
<input type="submit" name="remove" value="Remove Item">
</form>
</td>
</tr>
<%
}
}
}
%>
</table>
</body>l>
Controller (Servlet doPost method): addToCart.java
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
processRequest(request, response);
request.getSession();
String id = request.getParameter("id");
String itemName = request.getParameter("itemName");
String qty = request.getParameter("qty");
Item item = new Item();
item.setItemId(id);
item.setItemName(itemName);
item.setQty(Integer.parseInt(qty));
ArrayList<Item> arrayList = new ArrayList<Item>();
request.getSession().setAttribute("array", arrayList);
arrayList.add(item);
if(request.getServletContext().getAttribute("cartItemList") != null)
{
// attempt to UPDATE Quantity if the same item was previously added
if (arrayList.contains(id)) // if arrayList already contains the same id entered by user
{
Iterator<Item> it = arrayList.iterator();
//iterate through datas
int ctr = 0;
int total = item.getQty();
while (it.hasNext())
{
Item name = it.next();
//check if values matches
if (name.getItemId().equals(id))
{
total = name.getQty(); // add the new quantity to the existing one
}
else
{
ctr ;
}
}
arrayList = (ArrayList<Item>) request.getServletContext().getAttribute("cartItemList");
item = arrayList.get(ctr); // get the item at the index it was found
item.setQty(total); // set the quantity to the sum of the old quantoty and new quantity entered by user
//pass updated value to jsp page
request.getSession().setAttribute("cartItemList", arrayList);
request.getRequestDispatcher("index.jsp").forward(request, response);
request.getSession().setAttribute("cartItemList", arrayList);
}
else if (!arrayList.contains(id)) // if arrayList does not contain the same id entered by user
{
arrayList = (ArrayList<Item>) request.getServletContext().getAttribute("cartItemList");
arrayList.add(item);
request.getServletContext().setAttribute("cartItemList", arrayList);
}
}
else
{
request.getServletContext().setAttribute("cartItemList", arrayList);
}
response.sendRedirect("index.jsp");
}
Model: Item.java
public class Item {
private String itemId;
private String itemName;
private int qty;
private String submit;
public String getItemId() {
return itemId;
}
public void setItemId(String itemId) {
this.itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getQty() {
return qty;
}
public void setQty(int qty) {
this.qty = qty;
}
}
I have marked in addToCart.java
the part where I tried to create the code for updating the certain row with its new quantity. I just don't know what code I should place so that it updates the existing quantity rather than creating a new row. Thanks in advance for the help!
CodePudding user response:
arrayList.contains(id)
will never be the same because of the object. You must implement equals
and hashcode
in the Item class.
public class Item {
private String itemId;
private String itemName;
private int qty;
private String submit;
public String getItemId() {
return itemId;
}
public void setItemId(String itemId) {
this.itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getQty() {
return qty;
}
public void setQty(int qty) {
this.qty = qty;
}
@Override
public int hashCode() {
return Objects.hash(itemId);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Item)) {
return false;
}
Item other = (Item) obj;
return Objects.equals(itemId, other.itemId);
}
}
Above code with check if itemId is same then consider that object same although qty is different.
Also. logic to find the existing item and update seems to be wrong. You need to break for loop if the item matches. Update code in addToCart.java.
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
processRequest(request, response);
request.getSession();
String id = request.getParameter("id");
String itemName = request.getParameter("itemName");
String qty = request.getParameter("qty");
Item item = new Item();
item.setItemId(id);
item.setItemName(itemName);
item.setQty(Integer.parseInt(qty));
ArrayList<Item> arrayList = new ArrayList<>();
if (request.getServletContext().getAttribute("cartItemList") != null) {
arrayList = (ArrayList<Item>) request.getServletContext().getAttribute("cartItemList");
// attempt to UPDATE Quantity if the same item was previously added
if (arrayList.contains(item)) {
Item existingItem = arrayList.get(arrayList.indexOf(item));
existingItem.setQty(existingItem.getQty() item.getQty());
// pass updated value to jsp page
request.getSession().setAttribute("cartItemList", arrayList);
request.getRequestDispatcher("index.jsp").forward(request, response);
request.getSession().setAttribute("cartItemList", arrayList);
} else {
arrayList.add(item);
request.getServletContext().setAttribute("cartItemList", arrayList);
}
} else {
arrayList.add(item);
request.getServletContext().setAttribute("cartItemList", arrayList);
}
response.sendRedirect("index.jsp");
}
More details https://initialcommit.com/blog/working-hashcode-equals-java