day60
购物车案例补充
设置欢迎页
打开也系统,就可以直接看到商品列表页面
之前曾经设置过欢迎页,都是针对页面,可以有html页面,也可以有jsp页面
但是今天我们将一个servlet设置成欢迎页
在web.xml文件中设置欢迎页
<welcome-file-list> <welcome-file>BookServlet</welcome-file> </welcome-file-list>直接访问该项目,会直接访问BookServlet请求所对应的Servlet
实现商品列表功能
BookServlet.java
package com.saas.servlet; import com.saas.service.IBookService; import com.saas.service.impl.BookServiceImpl; import com.saas.entity.Book; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; @WebServlet(name = "BookServlet", value = "/BookServlet") public class BookServlet extends HttpServlet { private IBookService bookService = new BookServiceImpl(); @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String action = req.getParameter("action"); if(action == null){ getAllBooks(req, resp); }else if ("detail".equalsIgnoreCase(action)){ getBookDetail(req, resp); } } protected void getBookDetail(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String sbid = req.getParameter("bid"); int bid = sbid == null ? 0 : Integer.parseInt(sbid); Book book = bookService.getBookDetail(bid); req.setAttribute("book", book); req.getRequestDispatcher("book.jsp").forward(req, resp); } protected void getAllBooks(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { List<Book> list = bookService.getAllBooks(); req.setAttribute("books", list); req.getRequestDispatcher("books.jsp").forward(req, resp); } }在service方法中,由于没有传递任何的action,所以action为空,则执行getAllBooks()方法
在getAllBooks()方法中,借助service和dao完成查询所有的Book对象列表
IBookService.java
package com.saas.service; import com.saas.entity.Book; import java.util.List; public interface IBookService { List<Book> getAllBooks(); Book getBookDetail(int bid); }BookServiceImpl.java
package com.saas.service.impl; import com.saas.dao.IBookDao; import com.saas.dao.impl.BookDaoImpl; import com.saas.entity.Book; import com.saas.service.IBookService; import java.util.List; public class BookServiceImpl implements IBookService { private IBookDao bookDao = new BookDaoImpl(); @Override public List<Book> getAllBooks() { return bookDao.getAllBooks(); } @Override public Book getBookDetail(int bid) { return bookDao.getBookDetail(bid); } }IBookDao.java
package com.saas.dao; import com.saas.entity.Book; import java.util.List; public interface IBookDao { List<Book> getAllBooks(); Book getBookDetail(int bid); }BookDaoImpl.java
package com.saas.dao.impl; import com.saas.dao.IBookDao; import com.saas.entity.Book; import com.saas.util.DruidUtil; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import java.sql.SQLException; import java.util.List; public class BookDaoImpl implements IBookDao { private QueryRunner qr = new QueryRunner(DruidUtil.getDataSource()); @Override public List<Book> getAllBooks() { try { return qr.query("select * from book", new BeanListHandler<Book>(Book.class)); } catch (SQLException e) { throw new RuntimeException(e); } } @Override public Book getBookDetail(int bid) { try { return qr.query("select * from book where bid = ?", new BeanHandler<Book>(Book.class), bid); } catch (SQLException e) { throw new RuntimeException(e); } } }通过BookService,BookDao与数据库交互后得到Book对象的list集合
在BookServlet的getAllBooks()方法中,将Book对象的list存储到request范围中,key为books
跳转到books.jsp页面
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2024/5/27 Time: 8:47 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>books</title> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <style> td:{ margin: 10px; text-align: center; } </style> </head> <body> <c:if test="${empty books}"> nothing </c:if> <c:if test="${not empty books}"> <table width="80%" align="center"> <c:set var="count" value="0" /> <tr> <c:forEach items="${books}" var="book"> <td> <center> <a href="BookServlet?action=detail&bid=${book.bid}"><img src="imgs/${book.img}" width="100" height="100"/><br /></a><br /> ${book.name}<br /> <del>${book.nprice}</del><br /> ${book.oprice}<br /> </center> </td> <c:set var="count" value="${count+1}" /> <c:if test="${count%5==0}"> </tr> <tr> </c:if> </c:forEach> </tr> </table> </c:if> </body> </html>在books.jsp页面中分别判断books是否为空,为空显示nothing,不为空,把数据遍历到表格中显示
该页面还要进行一个分行处理,每隔五个表格的单元格之后进行换行操作,借助jstl的set属性用count来进行判断处理
在该页面中还设置了图片的超链接,点击图片之后,发送一个请求为以下内容BookServlet?action=detail&bid=${book.bid}
那么该请求继续交给BookServlet进行处理,action目前的值是detail,则在BookServlet中的service方法进行分支处理后会调用getBookDetail()方法进行进一步的处理
在该getBookDetail()方法中,由于刚刚的url中还含有bid的值,再该方法中拿到bid之后进行处理,再借助Book的service和dao进行根据bid查找Book对象
在当前servlet中再次将查询出来的book对象存储在key值为book的request作用范围内
最后跳转到book.jsp页面
book.jsp
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2024/5/27 Time: 11:29 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>book</title> <style> table{ align: center; } </style> </head> <body> <h1>this is book detail page</h1> <form action="CartServlet" method="post"> <input type="hidden" name="bid" value="${book.bid}"> <table align="center" width="30%"> <tr> <td rowspan="4"><img src="imgs/${book.img}" /></td> <td> ${book.bid} </td> </tr> <tr> <td> ${book.name} </td> </tr> <tr> <td> <del>${book.nprice}</del> </td> </tr> <tr> <td> ${book.oprice} </td> </tr> <tr> <td> <input type="submit" value="加入购物车"/> </td> </tr> </table> <form> </body> </html>在当前book.jsp页面中,分别显示之前点击书籍商品的详情信息
用户点击加入购物车按钮
由于当前按钮是一个提交按钮,会触发该按钮锁对应的form表的action请求
该action请求的url内容为CartServlet
CartServlet.java
package com.saas.servlet; import com.saas.entity.Book; import com.saas.entity.CartItem; import com.saas.service.IBookService; import com.saas.service.impl.BookServiceImpl; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.HashMap; import java.util.Map; @WebServlet(urlPatterns = "/CartServlet") public class CartServlet extends HttpServlet { private IBookService iBookService = new BookServiceImpl(); @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String sbid = req.getParameter("bid"); int bid = sbid == null ? 0 : Integer.parseInt(sbid); Book book = iBookService.getBookDetail(bid); HttpSession session = req.getSession(); Object objCart = session.getAttribute("cart"); if (objCart == null) { Map<Integer, CartItem> cart = new HashMap<>(); cart.put(bid, new CartItem(1, book)); session.setAttribute("cart", cart); } else{ if (objCart instanceof Map) { Map<Integer, CartItem> cart = (Map<Integer, CartItem>) objCart; if (cart.containsKey(bid)) { CartItem item = cart.get(bid); item.setCount(item.getCount() + 1); } else { cart.put(bid, new CartItem(1, book)); } session.setAttribute("cart", cart); } } resp.sendRedirect("cart.jsp"); } }CartItem.java
package com.saas.entity; public class CartItem { private int count; private Book book; public CartItem() { } public CartItem(int count, Book book) { this.count = count; this.book = book; } @Override public String toString() { return "CartItem{" + "count=" + count + ", book=" + book + '}'; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } }Book.java
package com.saas.entity; public class Book { private int bid; private String name; private String img; private double oprice; private double nprice; @Override public String toString() { return "Book{" + "bid=" + bid + ", name='" + name + '\'' + ", img='" + img + '\'' + ", oprice=" + oprice + ", nprice=" + nprice + '}'; } public int getBid() { return bid; } public void setBid(int bid) { this.bid = bid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getImg() { return img; } public void setImg(String img) { this.img = img; } public double getOprice() { return oprice; } public void setOprice(double oprice) { this.oprice = oprice; } public double getNprice() { return nprice; } public void setNprice(double nprice) { this.nprice = nprice; } }cart.jsp
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2024/5/27 Time: 11:53 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>cart</title> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> </head> <body> <h1>this is cart page.</h1> <c:if test="${empty cart}"> nothing </c:if> <c:if test="${not empty cart}"> <table width="80%" align="center" border="1"> <tr> <th>name</th> <th>image</th> <th>oprice</th> <th>nprice</th> <th>count</th> <th>summary</th> </tr> <c:forEach items="${cart}" var="c"> <tr> <td>${c.value.book.name}</td> <td><img src="imgs/${c.value.book.img}" width="100" height="100"/></td> <td>${c.value.book.oprice}</td> <td>${c.value.book.nprice}</td> <td>${c.value.count}</td> <td>${c.value.count * c.value.book.nprice}</td> </tr> </c:forEach> </table> </c:if> </body> </html>该页面使用jstl进行数据的展示,以及各种运算
购物车基本实现
小结
购物车主要是针对于session的使用
session中的数据结构Map的使用
目前关于购物车的实现是基于session的,一旦关闭浏览器,则失效
最好的做法是购物车再存入数据库中,随时可以拿到数据库中的信息