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(); @Overrideprotected 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(); @Overridepublic List<Book> getAllBooks() {return bookDao.getAllBooks();} @Overridepublic 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());@Overridepublic List<Book> getAllBooks() {try {return qr.query("select * from book", new BeanListHandler<Book>(Book.class));} catch (SQLException e) {throw new RuntimeException(e);}} @Overridepublic 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();@Overrideprotected 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;}@Overridepublic 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;@Overridepublic 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的,一旦关闭浏览器,则失效
最好的做法是购物车再存入数据库中,随时可以拿到数据库中的信息