I have an assignment where I'm supposed to make a simple website using EJB, JPA, JSP and some other stuff such as CSS and javascript.
I'm trying to send a list containing all the products that are stored in my database. I first create and populate a list with the ProductType objects in my servlet which is then passed to my JSP through the RequestDispatcher. In my JSP I use JSTL to iterate through the list and print the names of the products.
Nothing gets printed however. And I know through earlier testing with the JSTL choose statement that the list is null. I also tried populating a list in the servlet and then "printing" the product names on my servlet. When I ran the servlet on my server the product names were shown. That tells me that it's not a problem with my database or the way I'm retrieving my ProductType objects/tuples but rather that something is wrong when I pass the list from my servlet to my JSP.
Here is my relevant servlet code:
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);
}
And here is my relevant code from my homePage.jsp file
<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>
Figured that I might aswell post the code for retrieving the ProductType objects too
Facade
@EJB
ProductTypeEAOLocal productTypeEAO;
public List<ProductType> getAllProducts() {
return productTypeEAO.getAllProductTypes();
}
ProductTypeEAOImpl
public List<ProductType> getAllProductTypes() {
return em.createQuery("SELECT p FROM ProductType p", ProductType.class).getResultList();
}
I'm not really sure what I'm doing wrong, I'm quite new to EJB and web-developement in general. From looking around online this seems like it's the way to go about it and I'm kind of at my wits end to be honest. Would very much appreciate some help.
Your problem is that you put list into the request:
but read it from the session, which is not existing so returns
null:Request attributes are correctly passed when you use
dispatcher.forward.So your JSTL code should look like this (remove the whole line that sets the
productListvariable as it is the line that nullifies the variable.):The
${productTypeList}expression will scan any scope for given attribute, but if you want to fix it to the request scope and only look in there you can use this form${requestScope.productTypeList}Make sure that you use same name as you have once
productTypeListand thenproductList.Also remove the line:
as if you use the
dispatcher.forwardyou shouldn't write to the response, before you forward.One additional comment is that it looks like you have way too many layers for such simple app. You should just inject
@EJBwhich should be your DAO and Facade in your servlet code and in EJB useEntityManager. There is no point to have Facade if you just have one DAO. It is only useful when you want to hide your DB complexity from the servlet layer.Also dont create interfaces if you just have single implementation, waist of time and makes code harder to maintain. When you will have need for many implementations you can always refactor your code.