購物車採用session儲存,結構為Map<String,Integer>。Key為isbn號,值為購入數。
Map中不儲存Book物件,只儲存isbn以節省空間。
已登入的用戶可以查看購物車,網址前綴一樣使用/user/*
localhost:8080/BookShop/user/ShopCarSvl
新建ShopCarSvl
@WebServlet("/user/ShopCarSvl")
public class ShopCarSvl extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object obj = request.getSession().getAttribute("ShopCar");
Map<String,Integer> isbns = (Map<String,Integer>)obj;
BookBiz biz = new BookBiz();
try {
//從ShopCar把所有的isbn都交給getBook()去找書。
List<TBook> books = biz.getBooks(isbns.keySet());
request.setAttribute("books", books);
request.getRequestDispatcher("/WEB-INF/main/ShopCar.jsp").forward(request, response);
}catch(Exception e) {
Log.logger.error(e.getMessage());
request.setAttribute("msg", "系統忙碌中,請稍後再試");
request.getRequestDispatcher("/error.jsp").forward(request, response);
}
}
在BookBiz中新增getBooks()
public List<TBook> getBooks(Set<String> isbns) {
List<TBook> books = null;
IBookDao dao = new BookDaoMysql();
try {
if(isbns.size() > 0) {
books = dao.getBooks(isbns);
}
}finally {
dao.closeConnection();
}
}
在BookDaoMysql中新增getBooks()
public List<TBook> getBooks(Set<String> isbns) throws Exception{
List<TBook> books = null;
String strIsbns = "";
int ii = 0;
for(String isbn:isbns) {
if(ii == 0) {
strIsbns = "'" + isbn + "'";
}else {
strIsbns = strIsbns + "," + "'" + isbn + "'";
}
ii++;
}
String sql = "select isbn,bname,press,price,pdate from tbook where isbn in (" + strIsbns + ")";
this.openConnection();
PreparedStatement ps = this.connection.prepareStatement(sql);
ps.setString(1, strIsbns);
ResultSet rs = ps.executeQuery();
if(rs != null) {
books = new ArrayList<TBook>();
while(rs.next()) {
TBook book = new TBook();
book.setBname(rs.getString("bname"));
book.setIsbn(rs.getString("isbn"));
book.setPdate(rs.getString("Pdate"));
book.setPress(rs.getString("press"));
book.setPrice(rs.getString("price"));
books.add(book);
}
}
rs.close();
ps.close();
return books;
}
新建ShopCar.jsp
" <form action=""<%=basePath%>user/ShopCarSvl"" method=""post"">
<table align=""center"" width=90%>
<tr><td align=""right""><jsp:include page=""mhead.jsp""></jsp:include></td></tr>
<tr>
<td>
<table border=""1"" width=100%>
<tr><td>書名</td><td>商品價格</td><td width=""5%"">數量</td><td>操作</td></tr>
<c:forEach var=""bk"" items=""${books }"">
<tr>
<td>${bk.bname }</td>
<td>${bk.price }</td>
<td><input type=""text"" name=""${bk.isbn }"" value=""1""></td>
<td><a href=""<%=basePath%>user/ShopCarRemoveSvl?isbn=${bk.isbn }"">移除</a></td>
</tr>
</c:forEach>
</table>
</td>
</tr>
<tr>
<td align=""center"">
<c:if test=""${books.size()>0 }"">
<input type=""submit"" value=""結帳"">
</c:if>
<a href=""<%=basePath%>MainSvl>"">返回</a>
</td>
</tr>
</table>
</form>"
在商品明細頁,可以添加商品至購物車。若用戶未登入則由過濾器導向登入頁面。
新增"加入購物車"按鈕
<a href="<%=basePath%>user/ShopCarAddSvl?isbn=${bk.isbn }">加入購物車</a>
新建ShopCarAddSvl
@WebServlet("/user/ShopCarAddSvl")
public class ShopCarAddSvl extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String isbn = request.getParameter("isbn");
if(isbn == null) {
throw new ServletException("未找到isbn");
}
Object obj = request.getSession().getAttribute("ShopCar");
Map<String,Integer> shopCar = (Map<String,Integer>)obj;
shopCar.put(isbn, 1);
request.getRequestDispatcher("/user/ShopCarSvl").forward(request, response);
}
從購物車移除商品
<a href="<%=basePath%>user/ShopCarRemoveSvl?isbn=${bk.isbn }">移除</a>
新增ShopCarRemoveSvl
@WebServlet("/user/ShopCarRemoveSvl")
public class ShopCarRemoveSvl extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String isbn = request.getParameter("isbn");
Object obj = request.getSession().getAttribute("ShopCar");
Map<String,Integer> isbns = (Map<String,Integer>)obj;
isbns.remove(isbn);
request.getRequestDispatcher("/user/ShopCarSvl").forward(request, response);
}
在購物車的商品一覽頁面有結算按鈕,點擊前往CheckoutSvl,並攜帶商品列表中的isbns作為參數。
isbns是由<c:forEach>動態產生如下:
<c:forEachvar="bk"items="${books}">
<tr><td><inputtype="text"name="${bk.isbn}"value="1"></td></tr>
</c:forEach>
新建CheckoutSvl
@WebServlet("/user/CheckoutSvl")
public class CheckoutSvl extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object obj = request.getSession().getAttribute("ShopCar");
Map<String,Integer> isbns = (Map<String,Integer>)obj;
BookBiz biz = new BookBiz();
try {
//利用ShopCar內的isbns取得DB內的books列表
List<TBook> books = biz.getBooks(isbns.keySet());
//遍歷books,利用isbn當key,取得購買數量(value)
for(TBook book:books) {
String value = request.getParameter(book.getIsbn());
int bookCount = 1;
try {
//若用戶輸入數量不為空
if(value != null && !value.trim().equals("")) {
bookCount = Integer.parseInt(value);
//將購買數量設定到book物件內
book.setBuyCount(bookCount);
isbns.put(book.getIsbn(), bookCount);
}
}catch(Exception e){
//無法判斷的數量當作1處理
Log.logger.error("購買數量應為整數:" + e.getMessage());
book.setBuyCount(1);
isbns.put(book.getIsbn(), 1);
}
//計算總額
double allMoney = 0;
for(TBook bk:books) {
allMoney = allMoney + bk.getPrice()*bk.getBuyCount();
}
request.setAttribute("books", books);
request.setAttribute("allMoney", allMoney);
request.getRequestDispatcher("/WEB-INF/main/Checkout.jsp").forward(request, response);
}
}catch(Exception e) {
request.setAttribute("msg", "系統忙碌中,請稍後再試");
request.getRequestDispatcher("/error.jsp").forward(request, response);
}
}
新建Checkout.jsp
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
(中略..)
<form action="<%=basePath%>user/PayMoneySvl" method="post">
<table align="center" width=90%>
<tr><td align="right"><jsp:include page="mhead.jsp"></jsp:include></td></tr>
<tr>
<td>
<table border="1" width=100%>
<tr><td>書名</td><td>出版社</td><td>商品價格</td><td width="5%">數量</td></tr>
<c:forEach var="bk" items="${books }">
<tr>
<td>${bk.bname }</td>
<td>${bk.press }</td>
<td>${bk.price }</td>${bk.buyCount }本
</tr>
</c:forEach>
<tr>
<td colspan="4" align="center">帳戶餘額:"$"${user.account } 商品總價:"$"
<fmt:formatNumber value="${allMoney }" pattern="#.00" type="number"></fmt:formatNumber>
<input type="hidden" name="allMoney" value="${allMoney }">
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="center">
<c:if test="${user.account >= allMoney }">
<input type="submit" value="確認付款">
</c:if>
<a href="<%=basePath%>MainSvl>">返回</a>
</td>
</tr>
</table>
</form>