将 Controller Servlet 中指向产品或类别的链接显示到 jsp 页面中

Displaying Links to Products or Categories from the Controller Servlet into jsp pages

我正在尝试在用户选择给定产品后 link 产品到他们自己的 jsp 页面。我做错了什么,因为数据不会在 product.jsp.

上显示一次

我尝试使用变量 selectedProduct 检索数据,但应用程序似乎无法识别它或不知道从何处检索变量 selectedProduct 的数据。

我不知道为什么,因为在我看来,selectedProductselectedCategory 相同...显然不是...为什么?我错过了什么吗?

过去一周我一直在研究解决方案。我们非常欢迎任何帮助!

控制器 Servlet:

package controller;


import cart.ShoppingCart;
import wishlist.Wishlist;
import entity.Category;
import entity.Product;
import java.io.IOException;
import java.util.Collection;
import javax.ejb.EJB;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import session.CategoryFacade;
import session.ProductFacade;

public class ControllerServlet extends HttpServlet {


    @EJB
    private CategoryFacade categoryFacade;
    @EJB
    private ProductFacade productFacade;

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

        String userPath = request.getServletPath();
        HttpSession session = request.getSession();
        Category selectedCategory;
        Product selectedProduct;
        Collection<Product> categoryProducts;



      // if category page is requested
            if (userPath.equals("/category")) {

                // get categoryId from request
                String categoryId = request.getQueryString();

                if (categoryId != null) {

                    // get selected category
                    selectedCategory = categoryFacade.find(Short.parseShort(categoryId));

                    // place selected category in session scope
                    session.setAttribute("selectedCategory", selectedCategory);

                    // get all products for selected category
                    categoryProducts = selectedCategory.getProductCollection();

                    // place category products in session scope
                    session.setAttribute("categoryProducts", categoryProducts);
                }


            // if product page is requested
            if (userPath.equals("/product")) {

                // get productId from request
                String productId = request.getQueryString();

                 if (productId != null) {

                // get selected product
                selectedProduct = productFacade.find(Short.parseShort(productId));

// place selected product in session scope
                session.setAttribute("selectedProduct", selectedProduct);
            }}

根据要求编辑

Product.java:

package entity;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author PC
 */
@Entity
@Table(name = "product")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Product.findAll", query = "SELECT p FROM Product p"),
    @NamedQuery(name = "Product.findById", query = "SELECT p FROM Product p WHERE p.id = :id"),
    @NamedQuery(name = "Product.findByName", query = "SELECT p FROM Product p WHERE p.name = :name"),
    @NamedQuery(name = "Product.findByPrice", query = "SELECT p FROM Product p WHERE p.price = :price"),
    @NamedQuery(name = "Product.findByDescription", query = "SELECT p FROM Product p WHERE p.description = :description"),
    @NamedQuery(name = "Product.findByLastUpdate", query = "SELECT p FROM Product p WHERE p.lastUpdate = :lastUpdate")})
public class Product implements Serializable {
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 45)
    @Column(name = "price")
    private BigDecimal price;
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @NotNull
    @Lob
    @Size(min = 1, max = 16777215)
    @Column(name = "name")
    private String name;
    @Lob
    @Size(max = 2147483647)
    @Column(name = "description")
    private String description;
    @Basic(optional = false)
    @NotNull
    @Column(name = "last_update")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastUpdate;
    @JoinColumn(name = "category_id", referencedColumnName = "id")
    @ManyToMany(mappedBy = "productCollection")
    private Collection<Category> categoryCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "product")
    private Collection<OrderedProduct> orderedProductCollection;


    /**
     *
     */
    public Product() {
    }

    /**
     *
     * @param id
     */
    public Product(Integer id) {
        this.id = id;
    }

    /**
     *
     * @param id
     * @param name
     * @param price
     * @param lastUpdate
     */
    public Product(Integer id, String name, BigDecimal price, Date lastUpdate) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.lastUpdate = lastUpdate;
    }

    /**
     *
     * @return
     */
    public Integer getId() {
        return id;
    }

    /**
     *
     * @param id
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     *
     * @return
     */
    public String getName() {
        return name;
    }


    /**
     *
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }


    /**
     *
     * @return
     */
    public String getDescription() {
        return description;
    }

    /**
     *
     * @param description
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     *
     * @return
     */
    public Date getLastUpdate() {
        return lastUpdate;
    }

    /**
     *
     * @param lastUpdate
     */
    public void setLastUpdate(Date lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    /**
     *
     * @return
     */
    @XmlTransient
    public Collection<Category> getCategoryCollection() {
        return categoryCollection;
    }

    /**
     *
     * @param categoryCollection
     */
    public void setCategoryCollection(Collection<Category> categoryCollection) {
        this.categoryCollection = categoryCollection;
    }

    /**
     *
     * @return
     */
    @XmlTransient
    public Collection<OrderedProduct> getOrderedProductCollection() {
        return orderedProductCollection;
    }

    /**
     *
     * @param orderedProductCollection
     */
    public void setOrderedProductCollection(Collection<OrderedProduct> orderedProductCollection) {
        this.orderedProductCollection = orderedProductCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Product)) {
            return false;
        }
        Product other = (Product) object;
        return !((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id)));
    }

    @Override
    public String toString() {
        return "entity.Product[ id=" + id + " ]";
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}

Product.jsp

<table style="text-align: left; width: 100%; height: 172px;" border="0" cellpadding="0" cellspacing="0">

    <tbody>
        <tr>
            <td colspan="1" rowspan="6" style="vertical-align: top;">product_gallery<br></td>
            <td colspan="1" rowspan="6" style="vertical-align: top;"><img class="img" src="${initParam.productBigImagePath}${product.name}.jpg"><br></td>
            <td style="vertical-align: top;">${selectedProduct.name}<br></td>
            <td style="vertical-align: top;"><br></td>
        </tr>
        <tr>
            <td style="vertical-align: top;">$ ${selectedProduct.price}</td>
            <td style="vertical-align: top;"><br></td>
        </tr>
        <tr>
            <td style="vertical-align: top;"><br></td>
            <td style="vertical-align: top;"><br></td>
        </tr>
        <tr>
            <td style="vertical-align: top;"><br></td>
            <td style="vertical-align: top;"><br></td>
        </tr>
        <tr>
            <td colspan="2" rowspan="1" style="vertical-align: top;">${selectedProduct.description}</td>
        </tr>
        <tr>
            <td style="vertical-align: top;">
                <form action="addToWishlist" method="post"><br><br> 
                    <input name="productId" value="${product.id}" type="hidden"> 
                    <input class="submit" onclick="addedWishlist()" value="<fmt:message key='AddToWishlist'/>" type="submit"> 
                </form><br>
            </td>
            <td style="vertical-align: top;">
                <form action="addToCart" method="post"><br><br> 
                    <input name="productId" value="${product.id}" type="hidden">
                    <input class="submit" onclick="addedCart()" value="<fmt:message key='AddToCart'/>" type="submit"> 
                </form>
            </td>
        </tr>
        <tr>
            <td style="vertical-align: top;"><br></td>
            <td style="vertical-align: top;"><br></td>
            <td colspan="2" rowspan="1" style="vertical-align: top;">
                <ul>
                    <li style="background-color: rgb(198, 255, 201); width:100%; text-align:center; border-radius:2em;">
                        <a href="${value}"><fmt:message key='ContinueShopping'/></a>
                    </li>
                </ul>
                <br>
            </td>
        </tr>
    </tbody>
</table>

Category.jsp

<table style="text-align: left; width: 100%;" border="0" cellpadding="0" cellspacing="40px">

  <c:forEach var="product" items="${categoryProducts}" varStatus="iter">

    <td>
      <tbody>
        <tr>
          <td style="vertical-align: middle; text-align: center;" class="cell">
            <a href="product?${product.id}">



              <img class="img" alt="" src="${initParam.productImagePath}${product.name}.jpg" />

              <div class="caption">
                <br>view details</div>

            </a>
            <br>


          </td>
          <td style="vertical-align: middle; width: 140px; text-align: center; ">${product.name}
            <br>
          </td>
          <td style="vertical-align: middle; width: 120px; text-align: center; line-height:100%;">$${product.price}
            <br>
          </td>
          <td style="vertical-align: middle; width: 136px; text-align: center; line-height:20%;">

            <form id="wishlistForm" action="addToWishlist" method="post">
              <br>
              <br>
              <input name="productId" value="${product.id}" type="hidden">

              <input class="submit" onclick="addedWishlist()" value="<fmt:message key='AddToWishlist'/>" type="submit">
            </form>
            <br>
          </td>
          <td style="vertical-align: middle; width: 136px; text-align: center; line-height:20%;">


            <form id="cartForm" action="addToCart" method="post">
              <br>
              <br>

              <input name="productId" value="${product.id}" type="hidden">
              <input class="submit" onclick="addedCart()" value="<fmt:message key='AddToCart'/>" type="submit">


            </form>
            <br>
          </td>
        </tr>
      </tbody>
  </c:forEach>
</table>

您正在将 selectProduct 设置为单个产品的会话属性:

Product selectedProduct;
...
session.setAttribute("selectedProduct", selectedProduct);
JSTL 标签中的

<c:forEach> 用于 Collections, Lists or Arrays 而不是用于单个对象。

因此,您的第一个场景是正常的:<c:forEach var="product" items="${selectedProduct}" varStatus="iter"></c:forEach> 它是空白的,因为您不能迭代一个简单的 bean。

在您的第二个场景中,您正在迭代 ${categoryProducts}。我想你正在将这个对象设置为会话属性(它没有显示在你的代码片段中但肯定在它上面),至少这个对象是一个集合,所以在你的服务器中我想你已经:

Collection<Product> categoryProducts;
...
session.setAttribute("categoryProducts", categoryProducts); 

在这种情况下,如果您使用 <c:forEach var="product" items="${categoryProducts}" varStatus="iter"></c:forEach>,您将遍历该类别中的所有产品,这就是所有产品都出现在您的页面中的原因。

在你的第三种情况下,你使用的是 <c:forEach var="product" items="${categoryProducts}" varStatus="iter"></c:forEach>,所以你将循环的每个步骤从 categoryProducts 集合中分配一个元素到 product 对象,但是在这个循环中你使用 ${selectedProduct} 而不是 ${product} 所以对于每次迭代你使用相同的对象而不是对象从集合中给它。

我想如果你想在你的 product.jsp 中只显示一个 product,而这个 product 存储在 selectedProduct session attributte 上,那么解决你的问题不要使用 <c:forEach>,将其从 product.jsp 中删除(因为您只想显示一种产品),并在 jsp 代码中使用 ${selectedProduct.yourProperty} 而不是 ${product.yourProperty}.

根据评论进行编辑

尝试以下 product.jsp,如果它继续显示空白页,请检查您是否真的为您的产品设置了一个名为 selectedProduct 的会话属性,并且它的值为它是成员(selectProduct.getName()selectProduct.getDescription()selectProduct.getPrice() 不为空)。检查 if 中的代码,也许它从未执行过,或者如果它被执行了,你的 selectProduct 有一些空字段

       if (productId != null) {

            // get selected product
            selectedProduct = productFacade.find(Short.parseShort(productId));

            // place selected product in session scope
            session.setAttribute("selectedProduct", selectedProduct);
        }

Product.jsp:

<table style="text-align: left; width: 100%; height: 172px;" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td colspan="1" rowspan="6" style="vertical-align: top;">product_gallery<br></td>
            <td colspan="1" rowspan="6" style="vertical-align: top;"><img class="img" src="${initParam.productBigImagePath}${selectedProduct.name}.jpg"><br></td>
            <td style="vertical-align: top;">${selectedProduct.name}<br></td>
            <td style="vertical-align: top;"><br></td>
        </tr>
        <tr>
            <td style="vertical-align: top;">$ ${selectedProduct.price}</td>
            <td style="vertical-align: top;"><br></td>
        </tr>
        <tr>
            <td style="vertical-align: top;"><br></td>
            <td style="vertical-align: top;"><br></td>
        </tr>
        <tr>
            <td style="vertical-align: top;"><br></td>
            <td style="vertical-align: top;"><br></td>
        </tr>
        <tr>
            <td colspan="2" rowspan="1" style="vertical-align: top;">${selectedProduct.description}</td>
        </tr>
        <tr>
            <td style="vertical-align: top;">
                <form action="addToWishlist" method="post"><br><br> 
                    <input name="productId" value="${selectedProduct.id}" type="hidden"> 
                    <input class="submit" value="<fmt:message key='AddToWishlist'/>" type="submit"> 
                </form><br>
            </td>
            <td style="vertical-align: top;">
                <form action="addToCart" method="post"><br><br> 
                    <input name="productId" value="${selectedProduct.id}" type="hidden">
                    <input class="submit" value="<fmt:message key='AddToCart'/>"type="submit"> 
                </form>
            </td>
        </tr>
        <tr>
            <td style="vertical-align: top;"><br></td>
            <td style="vertical-align: top;"><br></td>
            <td colspan="2" rowspan="1" style="vertical-align: top;">
                <ul>
                    <li style="background-color: rgb(198, 255, 201); width:100%; text-align:center; border-radius:2em;">
                        <a href="${value}"><fmt:message key='ContinueShopping'/></a>
                    </li>
                </ul>
                <br>
            </td>
        </tr>
    </tbody>
</table>

希望这对您有所帮助,

编辑有效答案

// if product page is requested
        } else if (userPath.equals("/viewProduct")) {
            
            String productId = request.getQueryString();

            if (productId != null) {

                // get selected product
                selectedProduct = productFacade.find(Integer.parseInt(productId));

                // place selected product in session scope
                session.setAttribute("selectedProduct", selectedProduct);
                
            }
            
            userPath = "/product";