将List从servlet传递到JSP文件

tkclm6bt  于 2023-04-27  发布在  其他
关注(0)|答案(1)|浏览(185)

我有一个任务,我应该做一个简单的网站使用EJB,JPA,JSP和一些其他的东西,如CSS和JavaScript。
我试图发送一个包含存储在数据库中的所有产品的列表。我首先在servlet中创建并填充一个列表,然后通过RequestDispatcher将其传递给我的JSP。在我的JSP中,我使用JSTL遍历列表并打印产品的名称。
但是,没有任何内容被打印出来。通过前面使用JSTL choose语句进行的测试,我知道该列表为null。我还尝试在servlet中填充一个列表,然后在我的servlet上“打印”产品名称。当我在服务器上运行servlet时,显示了产品名称。这告诉我,这不是数据库或检索ProductType对象的方式的问题。元组,而是当我将列表从servlet传递到JSP时,发生了错误。
下面是我的相关servlet代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getWriter().append("Served at: ").append(request.getContextPath());
        List<ProductType> productTypes = facade.getAllProducts();
        
        // Set the list of product names as a request attribute
        request.setAttribute("productTypeList", productTypes);

        // Forward the request to the homePage.jsp page
        RequestDispatcher dispatcher = request.getRequestDispatcher("homePage.jsp");
        dispatcher.forward(request, response);
        
    }

下面是homePage.jsp文件中的相关代码

<p>
        Our products    
    </p>

    <%
     List<ProductType> productList = (List<ProductType>)session.getAttribute("productTypeList");
     request.setAttribute("productList", productList);
    %>
    <c:forEach items="${productTypeList}" var = "product">
        <p><c:out value="${product.getProductName()}"/></p>
    </c:forEach>

我想我也可以发布检索ProductType对象的代码
外观

@EJB
    ProductTypeEAOLocal productTypeEAO;

    public List<ProductType> getAllProducts() {
        return productTypeEAO.getAllProductTypes();
    }

产品类型EAOImpl

public List<ProductType> getAllProductTypes() {
        return em.createQuery("SELECT p FROM ProductType p", ProductType.class).getResultList();
    }

我真的不知道我做错了什么,我是相当新的EJB和Web开发的一般。从网上看这似乎是这样去做,我有点在我的智慧结束说实话。非常感谢一些帮助。

yrwegjxp

yrwegjxp1#

你的问题是你把list放入请求中:

request.setAttribute("productTypeList", productTypes);

但是从会话中读取它,会话不存在,因此返回null

List<ProductType> productList = (List<ProductType>)session.getAttribute("productTypeList");

当您使用dispatcher.forward时,正确传递请求属性。
因此,您的JSTL代码应该看起来像这样(删除设置productList变量的整行,因为它是使变量无效的那一行):

<c:forEach items="${productTypeList}" var = "product">
        <p><c:out value="${product.getProductName()}"/></p>
    </c:forEach>

${productTypeList}表达式将扫描给定属性的任何作用域,但如果您想将其固定到请求作用域并只在其中查找,则可以使用以下形式${requestScope.productTypeList}
请确保您使用相同的名称,因为您曾经productTypeList,然后productList
同时删除以下行:

response.getWriter().append("Served at: ").append(request.getContextPath());

如果你使用dispatcher.forward,你不应该在转发之前写入响应。
另外一个评论是,对于这样一个简单的应用程序来说,它看起来有太多的层。你应该在servlet代码中注入@EJB,这应该是你的DAO和Facade,而在EJB中使用EntityManager。如果你只有一个DAO,那么Facade就没有意义了。只有当你想从servlet层隐藏数据库复杂性时,它才有用。
另外,如果你只有一个实现,不要创建接口,这会浪费时间,而且会使代码更难维护。当你需要很多实现时,你可以重构你的代码。

相关问题