0

我正在用 java 构建一个简单的电子商务解决方案,但我陷入了一个关键点。我无法显示正确的项目。我正在使用一个 servlet,它有一个 doGet 一个购物车类、一个产品类和 viewcart.jsp 文件。为了在 servlet 之间传递项目,我使用了上下文的 setAttribute。这是我到目前为止构建的文件。谁能帮我解决这个问题?每次我按添加到汽车时,它都会添加元素,但看起来之前的所有元素都会被我添加的最后一个元素覆盖。

package com.kd.ecommerce;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

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;

/**
 * Servlet implementation class addtocart
 */
@WebServlet("/addtocart")
public class addtocart extends HttpServlet {
private static final long serialVersionUID = 1L;
private shoppingcart shop = new shoppingcart();

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ServletContext thisContext = getServletContext(); 
    String name = request.getParameter("product");
    Connection cn = DBConnect.getInstance();
    try {
        Statement st = cn.createStatement();
        ResultSet rs = st.executeQuery("select * from inventory where name = '"+name+"' LIMIT 1");
        while(rs.next()){
            Products p = new Products(rs.getString(2),rs.getString(3),rs.getString(4),rs.getFloat(5));
            System.out.println(p.getName()+":"+ p.getPrice());
            shop.ins(p);
            thisContext.setAttribute("shop", shop.getIt());
            for(int i = 0; i< shop.getIt().size(); i++){
                System.out.println(shop.getIt().get(i)+":"+ shop.getIt().get(i).getPrice());
            }
            response.sendRedirect("inventory.jsp?addedto=success");
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }

}


protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}

}

Products.java

package com.kd.ecommerce;

public class Products {
private static String name;
private static Float price;
private static String desc;
private static String img;

public Products(String n, String d, String i,Float p){
    name = n;
    price = p;
    desc = d;
    img = i;
}

public String getName(){
    return name;
}

public Float getPrice(){
    return price;
}

public String getImage(){
    return img;
}

public String getDesc(){
    return desc;
}
}

购物车.java

package com.kd.ecommerce;

import java.util.ArrayList;

public class shoppingcart {
private static ArrayList<Products> items;

public shoppingcart(){
    items = new ArrayList<Products>();
}

public void ins(Products p){
    items.add(p);
}

public void remove(Products p){
    items.remove(p);
}

public int getSize(){
    return items.size();
}

public ArrayList<Products> getIt(){
    return items;
}
}

viewcart.jsp

<jsp:include page="menu.jsp"></jsp:include>
<% 
ServletContext sc = getServletConfig().getServletContext();
if(sc.getAttribute("shop") != null){
    ArrayList<Products> it = (ArrayList<Products>)sc.getAttribute("shop");
    out.println(it);
    for(int i = 0; i< it.size(); i++){
        out.println("<span class='price'>"+it.get(i).getPrice()+"</span>");
    }
}else{
    out.println("<span class='empty'>Shopping cart empty</span>");
}
%>

- 编辑 -

我使用会话的新 viewcart.jsp

<% 
if(session.getAttribute("shop") != null){
    shoppingcart sh = (shoppingcart)session.getAttribute("shop");
    ArrayList<Products> pd = sh.getIt();
    for(int i = 0; i< pd.size(); i++){
        out.println("<span class='price'>"+pd.get(i).getPrice()+"</span>");
    }
}else{
    out.println("<span class='empty'>Shopping cart empty</span>");
}
%>
4

1 回答 1

1

导致您的问题的原因是您已将购物车设为 Servlet 中的实例变量。这意味着您的 Servlet 处理的每个 HTTP 请求都共享同一个shoppingcart。要解决此问题,请从类定义代码中移动以下行:

private shoppingcart shop = new shoppingcart();

并将其移至doGet方法中,位于以下行之前:

shop.ins(p);

doGet方法将包含以下两行:

shoppingcart shop = new shoppingcart();
shop.ins(p);

您甚至可以考虑为shoppingcart类提供一个构造函数,该构造函数将Products对象作为参数并在构造函数中设置项目。然后你可以将这两行合二为一,如下所示:

shoppingcart shop = new shoppingcart(p);

在 Servlet 中将对象定义为实例变量是一个常见的错误。请记住,对 servlet 的每个 HTTP 调用都将共享实例变量。如果您想为特定用户存储信息,请考虑将它们放入会话中。

- - 编辑 - -

事实证明,我实际上并没有回答这个问题。要保持添加项目的运行记录,您必须将项目保存到任何人都不会共享的地方 - 只有特定用户才能保存他的数据的地方。会议是专门为此目的而设计的地方。您可以在doGet方法中使用这样的会话:

HttpSession session = request.getSession(true);
shoppingcart shop = (shoppingcart)session.getValue("shop");
if(shop == null) {
    shop = new shoppingcart();
    session.putValue("shop", shop);
}

shop.ins(p);

从会话中获取值的行返回使用键“shop”存储的任何对象。如果这是用户添加的第一个项目,则尚未保存购物车,因此shop将为null。这就是我们进行空值检查的原因;创建一个购物车,然后将其与“shop”键关联,以便下次用户添加商品时,购物车将与“shop”键关联。

一旦我们有一个与该特定用户的“shop”键关联的购物车,您应该会看到在多次提交时将项目添加到同一个购物车对象中

于 2013-07-29T22:01:43.653 回答