JavaWeb專案練習--購物車模組、訂單模組
阿新 • • 發佈:2018-11-03
購物車模組
購物車儲存方式: 1)儲存在session中;此次專案儲存在session中 2)儲存在cookie中; 3)儲存在資料庫中: 不同方式的優缺點: 1.Session(Memcached)方式 優點:購物車資訊儲存在服務端,可以儲存1M 資訊。 缺點:1)對於大型網站會佔有過多的伺服器記憶體資源,造成伺服器壓力過大。 2)Session儲存的資訊會在使用者退出登入後丟失。使用者下次登入,購物車中商品資訊丟失,使用者只能從新選擇。 2.Cookie方式 優點:購物車資訊儲存在客戶端,不佔用伺服器資源,基本可以到達持久化儲存。 缺點:Cookie有大小的限制,不能超過4K,而且不夠安全、不能對使用者購買行為分析統計 如果是個人PC機,Cookie能很好的儲存購物車資訊. 但如果是公共辦公環境,Cookie儲存的資訊基本就失效了(會被其他人購物車資訊覆蓋)。 對於大型的電子商務網站,需要對使用者的購買行為進行分析,如果把購物車資訊儲存在Cookie中,則不能對使用者購買行為分析統計。 3.資料庫儲存 優點:持久化儲存,可以分析使用者購買行為。 缺點: 網站速度變慢,成本和維護增加。 1建立相關類 購物車的結構: CartItem:包含圖書和數量 Cart:包含一個Map<String,CartItem> dao:沒有 service:沒有 web.servlet:提供!CartServlet 修改登入方法,在使用者登入成功後,馬上在session中新增一輛車!!! 頁面:/jsps/cart/list.jsp 它只有一個任務,就是遍歷車! 車在session中,通過車可以得到所有的CartItem ${sessionScope.cart.cartItems} 2 新增購物車條目
3 清空條目
4 刪除購物車條目
5 我的購物車
top.jsp中存在一個連結:我的購物車
我的購物車直接訪問/jsps/cart/list.jsp,它會顯示session中車的所有條目
domian:
/** * 購物車類 * @author 一萬年行不行 * */ public class Cart { /* * map建立: * 1.建立Map存放條目,以書id做鍵<書id,條目> * 2.建立LinkedHashMap,為了保證順序 */ private Map<String,CartItem> map = new LinkedHashMap<String, CartItem>(); /** * 合計 (所有條目價錢小計之和) * 使用BigDecimal型別:解決二進位制運算誤差問題 * @return */ public double getTotal() { //使用BigDecimal型別 BigDecimal total = BigDecimal.valueOf(0); //遍歷每個條目 for (CartItem cartItem : map.values()) { //得到每個條目價錢(得到BigDecimal型別) BigDecimal subTatal = BigDecimal.valueOf(cartItem.getSubtotal()); //對每個條目進行加法求和 total = total.add(subTatal); } return total.doubleValue(); //轉為double型別 } /** * 新增條目 * @param cartItem */ public void add(CartItem cartItem){ /* * 1.判斷map中是否含有被新增條目 * 2.有,進行條目合併(合併數量) * 條目合併: * 1.拿到原條目 * 2.條目數量合併 (原數量 + 新數量) * 3.將合併後的條目放進map * 3.沒有,直接新增 */ if(map.containsKey(cartItem.getBook().getBid())){ //1.拿到原條目 CartItem _cartItem = map.get(cartItem.getBook().getBid()); //2.條目數量合併 (原數量 + 新數量) _cartItem.setCount(_cartItem.getCount() + cartItem.getCount()); //3.將合併後的條目放進map map.put(cartItem.getBook().getBid(), _cartItem); }else{ //直接存放 map.put(cartItem.getBook().getBid(),cartItem); } } /** * 刪除指定條目 * @param bid */ public void delete(String bid){ map.remove(bid); } /** * 清空條目 */ public void clear(){ map.clear(); } /** * 我的購物車(獲取所有條目) * @return */ public Collection<CartItem> getCartItems(){ return map.values(); } } /** * 購物條目 * @author 一萬年行不行 * */ public class CartItem { private Book book; //商品 private int count; //商品數量 /** * 小計方法:處理二進位制運算誤差問題 * @return */ public double getSubtotal(){ //計算方法,沒有對應成員 //將double轉化為BigDecimal型別:解決二進位制運算誤差問題 BigDecimal _price = BigDecimal.valueOf(book.getPrice()); BigDecimal _count = BigDecimal.valueOf(count); //計算價格(價錢*數量),並轉回double型別 return _price.multiply(_count).doubleValue(); } public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } }
servlet:
public class CartServlet extends BaseServlet { private static final long serialVersionUID = 1L; /** * 新增購物 條目 * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1.得到session中的車(只有登陸的使用者才有車) * 2.得到購買的圖書和數量 * 3.建立條目(條目包含圖書和數量屬性),並對條目設定圖書和購買數 * 4.新增條目到車中 */ Cart cart = (Cart) request.getSession().getAttribute("cart"); //得到條目,先得到圖書的id,通過id查詢資料庫,得到book String bid = request.getParameter("bid"); Book book = new BookService().load(bid); //得到使用者購買數量 int count = Integer.parseInt(request.getParameter("count")); //建立條目,並對條目設定圖書和購買數 CartItem cartItem = new CartItem(); cartItem.setBook(book); cartItem.setCount(count); cart.add(cartItem); return "f:/jsps/cart/list.jsp"; } /** * 刪除購物條目 * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1.得到車 * 2.得到要清空的條目ID * 3.根據ID刪除條目 */ Cart cart = (Cart) request.getSession().getAttribute("cart"); String bid = request.getParameter("bid"); cart.delete(bid); return "f:/jsps/cart/list.jsp"; } /** * 清空購物條目 * @param request * @param response * @return * @throws ServletException * @throws IOException */ public String clear(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1.得到車 * 2.清空車 */ Cart cart = (Cart) request.getSession().getAttribute("cart"); cart.clear(); return "f:/jsps/cart/list.jsp"; } }
jsp
list.jsp 顯示購物車中資訊
<style type="text/css">
* {
font-size: 11pt;
}
div {
margin:20px;
border: solid 2px gray;
width: 150px;
height: 150px;
text-align: center;
}
li {
margin: 10px;
}
#buy {
background: url(<c:url value='/images/all.png'/>) no-repeat;
display: inline-block;
background-position: 0 -902px;
margin-left: 30px;
height: 36px;
width: 146px;
}
#buy:HOVER {
background: url(<c:url value='/images/all.png'/>) no-repeat;
display: inline-block;
background-position: 0 -938px;
margin-left: 30px;
height: 36px;
width: 146px;
}
</style>
</head>
<body>
<h1>購物車</h1>
<c:choose>
<%-- 如果沒有車 或 車中沒有條目 則顯示圖片--%>
<c:when test="${empty sessionScope.cart or fn:length(sessionScope.cart.cartItems) eq 0 }">
<img src="<c:url value='/images/cart.png'/>" width="100"/>
<h1>您的購物車為空,快去商城挑選吧!</h1>
</c:when>
<c:otherwise>
<table border="1" width="100%" cellspacing="0" background="black">
<tr>
<td colspan="7" align="right" style="font-size: 15pt; font-weight: 900">
<a href="<c:url value='CartServlet?method=clear'/>">清空購物車</a>
</td>
</tr>
<tr>
<th>圖片</th>
<th>書名</th>
<th>作者</th>
<th>單價</th>
<th>數量</th>
<th>小計</th>
<th>操作</th>
</tr>
<c:forEach items="${sessionScope.cart.cartItems }" var="cartItem">
<tr>
<td><div><img src="<c:url value='/${cartItem.book.image }'/>"/></div></td>
<td>${cartItem.book.bname }</td>
<td>${cartItem.book.author }</td>
<td>${cartItem.book.price }元</td>
<td>${cartItem.count }</td>
<td>${cartItem.subtotal }元</td>
<td><a href="<c:url value='/CartServlet?method=delete&bid=${cartItem.book.bid }'/>">刪除</a></td>
</tr>
</c:forEach>
<tr>
<td colspan="7" align="right" style="font-size: 15pt; font-weight: 900">
合計:${sessionScope.cart.total }元
</td>
</tr>
<tr>
<td colspan="7" align="right" style="font-size: 15pt; font-weight: 900">
<a id="buy" href="<c:url value='/OrderServlet?method=add'/>"></a>
</td>
</tr>
</table>
</c:otherwise>
</c:choose>
</body>
訂單模組
1 建立相關類
domain:
Order
OrderItem
dao:OrderDao
service:OrderService
web.servlete:OrderServlet
2 生成訂單
3 我的訂單(按使用者查)
4 載入訂單(按id查)
5 確認收貨
domain:
/**
* 訂單類
* @author 一萬年行不行
*
*/
public class Order {
private String oid;
private Date ordertime; //下單時間
private double total; //合計
//訂單狀態(四種)
private int state; //1.未付款、2.付款未發貨、3.發貨未收貨、4.交易成功
private User owner; //訂單所有者
private String address; //收穫地址
private List<OrderItem> orderItemList; //當前訂單下所有商品條目
}
/**
* 訂單條目類
* @author 一萬年行不行
*
*/
public class OrderItem {
private String iid;
private int count; //數量
private double subtotal; //小計
private Book book; //所購買的圖書
private Order order; //所屬訂單
}
dao
public class OrderDao {
private QueryRunner qr = new TxQueryRunner();
/**
* 新增訂單
* @param order
*/
public void addOrder(Order order){
try {
String sql = "insert into orders values(?,?,?,?,?,?)";
//處理util的Date轉換成sqlTimestamp(sql中的時間型別與java中時間型別不同)
Timestamp timestamp = new Timestamp(order.getOrdertime().getTime());
Object[] params = {
order.getOid(),timestamp,
order.getTotal(),order.getState(),
order.getOwner().getUid(),
order.getAddress()};
qr.update(sql,params);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 新增訂單中商品條目
* @param orderItemList
*/
public void addOrderItemList(List<OrderItem> orderItemList){
/*
* QueryRunner類的batch(String sql, Object[][] params)
* 其中params是多個一維陣列!
* 每個一維陣列都與sql在一起執行一次,則多個一維陣列就執行多次
*/
try {
String sql = "insert into orderitem value(?,?,?,?,?)";
//對引數賦值 : 使用二維陣列(目的是使用批處理)。
/*
* 把orderItemList轉換為二維陣列,則可完成批處理
* 做法:
* 把每個OrderItem物件都轉換為一個一維陣列
*/
//第一個[]:指定二維陣列中一維陣列的個數
//第二個[]:指定每個一維陣列中元素的個數
Object[][] params = new Object[orderItemList.size()][];
/*
* 遍歷二維陣列orderItemList,得到一維陣列
* 使用條目對每組引數(一維陣列)賦值:
* 內部:使用每個orderItem的物件為params中每個引數賦值
*/
for (int i = 0; i < orderItemList.size(); i++) {
//得到每個條目(一維陣列)
OrderItem item = orderItemList.get(i);
//使用條目對每組引數(一維陣列)賦值
params[i] = new Object[]{
item.getIid(),item.getCount(),
item.getSubtotal(),item.getOrder().getOid(),
item.getBook().getBid()};
}
//執行批處理操作
qr.batch(sql,params);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 使用uid查詢訂單
* @param uid
* @return
*/
public List<Order> findByUid(String uid) {
/*
* 1.通過uid查詢出當前使用者的所有List<Order>
* 2.迴圈遍歷每個Order,載入每個Order下所有OrderItem
*/
try{
//1.得到當前使用者所有訂單
String sql = "select * from orders where uid= ? ";
List<Order> orderList = qr.query(sql, new BeanListHandler<Order>(Order.class),uid);
//2.迴圈遍歷每個Order,載入每個訂單下每個條目
for (Order order : orderList) {
loadOrderItems(order);
}
return orderList;
}catch(SQLException e){
throw new RuntimeException(e);
}
}
/**
* 載入指定Order的所有訂單條目
* 查詢結果為mapList,需要將mapListz轉為OrderItem
* @param order
* @throws SQLException
*/
private void loadOrderItems(Order order) throws SQLException {
//查詢兩張表:orderitem book
String sql = "select * from orderitem i, book b where i.bid=b.bid AND oid = ?";
/*
* 使用MapListHandler()結果集
* 因為一行結果集不再對應一個JavaBean,所以不能使用BeanListHandler。
*
* mapList是多個map,每個map對應多個結果集。
* map中的每個鍵值對為表的列名
*/
List<Map<String,Object>> mapList = qr.query(sql, new MapListHandler(),order.getOid());
/*
* 需求:
* 1)需要使用每一個map生成兩個物件:OrderItem和Book
* 2)然後建立兩者間關係(把Book設定給OrderItem)
* 3)最終得到一個OrderItem
* 做法:建立toOrderItemList()方法來完成。
*/
List<OrderItem> orderItemList = toOrderItemList(mapList);
order.setOrderItemList(orderItemList);
}
/**
* 把一大堆map生成一大堆OrderItem
* 使mapList中每個map生成兩個物件,並建立關係.
*
* @param mapList
* @return 一個完整的OrderItem
*/
private List<OrderItem> toOrderItemList(List<Map<String, Object>> mapList) {
/*
* 做法:
* 1.迴圈遍歷 每個map
* 2.建立方法完成2.3.(toOrderItem)
* 2.使map生成兩個物件
* 3.建立關係(把Book設定給OrderItem),最終結果為一個OrderItem
* 4.儲存OrderItem
*/
//建立集合:用來存放所有的 OrderItem
List<OrderItem> orderItemList = new ArrayList<OrderItem>();
for (Map<String, Object> map : mapList) {
OrderItem item = toOrderItem(map);
orderItemList.add(item);
}
return orderItemList;
}
/**
* 把一個Map轉換成一個OrderItem物件
* @param map
* @return
*/
private OrderItem toOrderItem(Map<String, Object> map) {
/*
* 做法:
* 1.使用toBean方法,使map分別轉換出兩個物件:OrderItem物件、Book物件
* 2.對OrderItem設定book屬性
* 3.返回OrderItem
*/
//1.使用toBean方法,使map轉換出OrderItem物件、Book物件
OrderItem orderItem = CommonUtils.toBean(map, OrderItem.class);
Book book = CommonUtils.toBean(map, Book.class);
//2.對OrderItem設定book屬性,完成返回
orderItem.setBook(book);
return orderItem;
}
/**
* 載入訂單
* @param oid
* @return
*/
public Order load(String oid){
try{
//1.得到訂單
String sql = "select * from orders where oid= ? ";
Order order = qr.query(sql, new BeanHandler<Order>(Order.class),oid);
//載入訂單下每個條目
loadOrderItems(order);
return order;
}catch(SQLException e){
throw new RuntimeException(e);
}
}
/**
* 查詢訂單狀態
* @param oid
* @return
*/
public int getStateByOid(String oid){
String sql = "select state from orders where oid = ?";
try {
Number num = (Number) qr.query(sql,new ScalarHandler(),oid);
return num.intValue();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 修改訂單狀態
* @param oid
* @param state
*/
public void updateState(String oid,int state){
String sql = "update orders set state=? where oid = ?";
try {
qr.update(sql,state,oid);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
service
public class OrderService {
private OrderDao orderDao = new OrderDao();
/**
* 新增訂單
* 處理事務
* @param order
*/
public void add(Order order){
try{
//開啟事務
JdbcUtils.beginTransaction();
orderDao.addOrder(order); //插入訂單
orderDao.addOrderItemList(order.getOrderItemList()); //插入訂單中商品條目
//提交事務
JdbcUtils.commitTransaction();
}catch(Exception e){
//事務回滾
try {
JdbcUtils.rollbackTransaction();
} catch (SQLException e1) {
}
throw new RuntimeException(e); //發生回滾,則丟擲異常
}
}
/**
* 我的訂單
* @param uid
* @return
*/
public List<Order> myOrders(String uid) {
// TODO Auto-generated method stub
return orderDao.findByUid(uid);
}
/**
* 載入訂單
* @param oid
* @return
*/
public Order load(String oid) {
// TODO Auto-generated method stub
return orderDao.load(oid);
}
/**
* 確認收貨
* @param oid
* @throws OrderException
*/
public void confirm(String oid) throws OrderException{
/*
* 校驗訂單狀態
* 不是3,丟擲異常
* 修改訂單狀態為4,表示交易成功
*/
int state = orderDao.getStateByOid(oid);
if(state != 3) throw new OrderException("訂單確認失敗。請按流程確認");
//修改狀態為4
orderDao.updateState(oid, 4);
}
/**
* 支付方法
* @param oid
*/
public void pay(String oid) {
/*
* 1. 獲取訂單的狀態
* * 如果狀態為1,那麼執行下面程式碼
* * 如果狀態不為1,那麼本方法什麼都不做
*/
int state = orderDao.getStateByOid(oid);
if(state == 1) {
// 修改訂單狀態為2
orderDao.updateState(oid, 2);
}
}
}
servlet
public class OrderServlet extends BaseServlet {
private static final long serialVersionUID = 1L;
private OrderService orderService = new OrderService();
/**
* 新增訂單
* 用session中的公務車生成訂單
*
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
public String add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 1.從session中得到cart
* 2.使用cart生成Order物件
* 3.呼叫service方法完成新增訂單
* 4.儲存order到request中,轉發到/jsps/order/desc.jsp
*/
Cart cart = (Cart) request.getSession().getAttribute("cart");
/* 2.
* 使用cart生成Order物件
* 並手動生成cart中沒有的(order中需要的)相關屬性
*
* Cart --> Order
*
*/
Order order = new Order();
order.setOid(CommonUtils.uuid()); //設定訂單編號
order.setOrdertime(new Date()); //設定下單時間(使用當前系統時間)
order.setState(1); //設定狀態為1,表示未付款
//得到當前使用者,設定訂單所有者
User user = (User) request.getSession().getAttribute("session_user");
order.setOwner(user); //設定訂單所有者
order.setTotal(cart.getTotal()); //設定訂單合計,從cart中獲取
//建立訂單條目(集合)
//cartItemList --> orderItemList
List<OrderItem> orderItemList = new ArrayList<OrderItem>();
//需要通過遍歷cart條目,對每個訂單條目屬性賦值)
for (CartItem cartItem : cart.getCartItems()) {
OrderItem oi = new OrderItem(); //建立訂單條目
oi.setIid(CommonUtils.uuid()); //設定條目ID
oi.setCount(cartItem.getCount()); //設定條目數量
oi.setBook(cartItem.getBook()); //設定條目的圖書
oi.setSubtotal(cartItem.getSubtotal()); //設定小計
oi.setOrder(order); //設定所屬訂單
orderItemList.add(oi); //把訂單條目新增到訂單條目集合中
}
//把所有訂單條目新增到訂單中
order.setOrderItemList(orderItemList);
//清空購物車
cart.clear();
/*
* 3.呼叫orderService完成新增訂單
*/
orderService.add(order);
//4.儲存order到request域,轉發
request.setAttribute("order", order);
return "f:/jsps/order/desc.jsp";
}
/**
* 我的訂單
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
public String myOrders(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 1.從session中得到當前使用者.
* 2.使用當前使用者uid呼叫orderService#myOrders(uid),
* --得到該使用者的所有訂單List<Order>
* 3.把訂單列表儲存到request域中
* 4.轉發到/jsps/order/list.jsp
*/
//得到當前使用者
User user = (User) request.getSession().getAttribute("session_user");
//得到該使用者的所有訂單List<Order>
List<Order> orderList = orderService.myOrders(user.getUid());
//把訂單列表儲存到request域中,並轉發
request.setAttribute("orderList", orderList);
return "f:/jsps/order/list.jsp";
}
/**
* 載入訂單
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
public String load(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 1.得到oid引數
* 2.使用oid呼叫service方法得到Order
* 3.儲存Order到request,轉發
*/
String oid = request.getParameter("oid");
request.setAttribute("order", orderService.load(oid));
return "f:/jsps/order/desc.jsp";
}
/**
* 確認收貨
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
public String confirm(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 1.獲取oid引數
* 2.呼叫service方法
* 異常:儲存異常資訊,轉發到msg.jsp
* 3.儲存成功資訊,轉發到msg.jsp
*/
String oid = request.getParameter("oid");
try {
orderService.confirm(oid);
request.setAttribute("msg", "恭喜!確認完成,交易成功");
} catch (OrderException e) {
request.setAttribute("msg", e.getMessage());
}
return "f:/jsps/msg.jsp";
}
jsp
1) desc.jsp顯示單個訂單詳細資訊
<body>
<h1>當前訂單</h1>
<table border="1" width="100%" cellspacing="0" background="black">
<tr bgcolor="gray" bordercolor="gray">
<td colspan="6">
訂單編號:${order.oid } 成交時間:<fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${order.ordertime }"/> 金額:<font color="red"><b>${order.total }元</b></font>
</td>
</tr>
<c:forEach items="${order.orderItemList }" var="orderItem">
<tr bordercolor="gray" align="center">
<td width="15%">
<div><img src="<c:url value='/${orderItem.book.image }'/>" height="75"/></div>
</td>
<td>書名:${orderItem.book.bname }</td>
<td>單價:${orderItem.book.price }元</td>
<td>作者:${orderItem.book.author }</td>
<td>數量:${orderItem.count }</td>
<td>小計:${orderItem.subtotal }</td>
</tr>
</c:forEach>
<c:url value=''/>
</table>
<br/>
<form method="post" action="<c:url value='/OrderServlet'/>" id="form" target="_parent">
<input type="hidden" name="method" value="pay"/>
<input type="hidden" name="oid" value="${order.oid} "/>
收貨地址:<input type="text" name="address" size="50" value="北京市海淀區金燕龍大廈2樓216室無敵收"/><br/>
選擇銀行:<br/>
<input type="radio" name="pd_FrpId" value="ICBC-NET-B2C" checked="checked"/>工商銀行
<img src="<c:url value='/bank_img/icbc.bmp'/>" align="middle"/>
<input type="radio" name="pd_FrpId" value="BOC-NET-B2C"/>中國銀行
<img src="<c:url value='/bank_img/bc.bmp'/>" align="middle"/><br/><br/>
<input type="radio" name="pd_FrpId" value="ABC-NET-B2C"/>農業銀行
<img src="<c:url value='/bank_img/abc.bmp'/>" align="middle"/>
<input type="radio" name="pd_FrpId" value="CCB-NET-B2C"/>建設銀行
<img src="<c:url value='/bank_img/ccb.bmp'/>" align="middle"/><br/><br/>
<input type="radio" name="pd_FrpId" value="BOCO-NET-B2C"/>交通銀行
<img src="<c:url value='/bank_img/bcc.bmp'/>" align="middle"/><br/>
</form>
<a id="pay" href="javascript:document.getElementById('form').submit();"></a>
</body>
2)list.jsp 遍歷顯示所有訂單
<body>
<h1>我的訂單</h1>
<table border="1" width="100%" cellspacing="0" background="black">
<c:forEach items="${orderList }" var="order">
<tr bgcolor="gray" bordercolor="gray">
<td colspan="6">
訂單編號:${order.oid } 成交時間:${order.ordertime } 金額:<font color="red"><b>${order.total }</b></font>
<!-- 根據狀態顯示不同提示資訊 -->
<c:choose>
<c:when test="${order.state eq 1 }">
<a href="<c:url value='/OrderServlet?method=load&oid=${order.oid }'/>">付款</a>
</c:when>
<c:when test="${order.state eq 2 }">等待發貨</c:when>
<c:when test="${order.state eq 3 }">
<a href="<c:url value='/OrderServlet?method=confirm&oid=${order.oid }'/>">確認收貨</a>
</c:when>
<c:when test="${order.state eq 4 }">交易成功</c:when>
</c:choose>
</td>
</tr>
<c:forEach items="${order.orderItemList }" var="orderItem">
<tr bordercolor="gray" align="center">
<td width="15%">
<div><img src="<c:url value='/${orderItem.book.image }'/>" height="75"/></div>
</td>
<td>書名:${orderItem.book.bname }</td>
<td>單價:${orderItem.book.price }</td>
<td>作者:${orderItem.book.author }</td>
<td>數量:${orderItem.count }</td>
<td>小計:${orderItem.subtotal }元</td>
</tr>
</c:forEach>
</c:forEach>
</table>
</body>