購物車案例【簡單版】

前言

爲了鞏固MVC的開發模式,下面就寫一個購物車的小案例..javascript

①構建開發環境

導入須要用到的開發包

image.png

創建程序開發包

image.png


②設計實體

書籍實體

    public class Book {

private String id;
private String name;
private String author;
private String description;
private double price;

public Book() {
}

public Book(String id, String name, String author, String description, double price) {
this.id = id;
this.name = name;
this.author = author;
this.description = description;
this.price = price;
}

//...各類setter和getter
}

購物車與購物項實體

可能咱們會這樣設計購物車html

    /*該類表明的是購物車*/
public class Cart {

//關鍵字是書籍的id,值是書
private Map<String, Book> bookMap = new LinkedHashMap<>();


}

上面的作法是不合適的,試想一下:若是我要購買兩本相同的書,購物車的頁面上就出現了兩本書,而不是書*2。買三本相同的書就在購物頁面上出現三本書,而不是書*3.java

所以,Map集合的值不能是Book對象,那咱們怎麼才能解決上面所說的問題呢?咱們最經常使用的就是,再寫一個實體CartItem(表明購物項)web

  • 好的,咱們先來寫購物項實體吧,等會再寫購物車!ajax

    /*購物項表明的是當前書,並表示該書出現了幾回*/
public class CartItem {

private Book book;
private int quantity;

//該購物項(書--不必定只有一本)的價錢應該等於書的數量*價格
private double price;


//書的價錢*數量
public double getPrice() {
return book.getPrice() * this.quantity;
}

public Book getBook() {
return book;
}

public void setBook(Book book) {
this.book = book;
}

public int getQuantity() {
return quantity;
}

public void setQuantity(int quantity) {
this.quantity = quantity;
}

public void setPrice(double price) {
this.price = price;
}
}
  • 購物車實體spring

    /*該類表明的是購物車*/
public class Cart {

//關鍵字是書籍的id,值是書
private Map<String, CartItem> bookMap = new LinkedHashMap<>();

//表明着購物車的總價
private double price;


//把購物項(用戶傳遞進來的書籍)加入到購物車裏邊去,也應該是購物車的功能
public void addBook(Book book) {

//獲取獲得購物項
CartItem cartItem = bookMap.get(book.getId());

//判斷購物車是否存在該購物項,若是不存在
if (cartItem == null) {

//建立這個購物項對象
cartItem = new CartItem();

//將用戶傳遞過來的書籍做爲購物項
cartItem.setBook(book);

//把該購物項的數量設置爲1
cartItem.setQuantity(1);

//把購物項加入到購物車去
bookMap.put(book.getId(), cartItem);
} else {

//若是存在該購物項,將購物項的數量+1
cartItem.setQuantity(cartItem.getQuantity() + 1);
}
}

//購物車的總價就是全部購物項的價格加起來
public double getPrice() {

double totalPrice = 0;

for (Map.Entry<String, CartItem> me : bookMap.entrySet()) {

//獲得每一個購物項
CartItem cartItem = me.getValue();

//將每一個購物項的錢加起來,就是購物車的總價了!
totalPrice += cartItem.getPrice();
}

return totalPrice;
}


public Map<String, CartItem> getBookMap() {
return bookMap;
}

public void setBookMap(Map<String, CartItem> bookMap) {
this.bookMap = bookMap;
}


public void setPrice(double price) {
this.price = price;
}
}
③數據庫

這裏就直接用集合模擬數據庫了,簡單的domo而已。數據庫

    //既然是購物車案例,應該會有增刪的操做,經過關鍵字查詢書籍,因此使用LinkedHashMap集合
private static Map<String, Book> map = new LinkedHashMap<>();

static {
map.put("1",new Book("1", "java", "zhongfucheng", "好書", 99));
map.put("2",new Book("2", "javaweb", "ouzicheng", "很差的書", 44));
map.put("3",new Book("3", "ajax", "xiaoming", "通常般", 66));
map.put("4",new Book("4", "spring", "xiaohong", "還行", 77));
}

public static Map<String, Book> getAll() {


return map;
}
④開發dao

dao層應該至少提供獲取全部的書籍和根據關鍵字獲取獲得書籍服務器

public class BookDao {

//獲取存放着書籍的Map集合
public Map getAll() {
return BookDB.getAll();
}

//根據關鍵字獲取某本書籍
public Book find(String id) {
return BookDB.getAll().get(id);
}
}
⑤開發service

service層就是對DAO層的一個封裝微信

    public class BusinessService {

BookDao bookDao = new BookDao();

/*列出全部的書*/
public Map getAll() {

return bookDao.getAll();
}

/*根據書的id獲取書*/
public Book findBook(String id) {
return bookDao.find(id);
}

//...待會還有其餘的功能再從這裏補充!
}
⑥開發web

列出全部的書

開發提供JSP頁面的Servlet

        //調用service層的方法,獲取獲得存放書籍的Map集合
BusinessService businessService = new BusinessService();
Map books = businessService.getAll();

//存放在request域對象中,交給jsp頁面顯示
request.setAttribute("books", books);

//跳轉到jsp頁面中
request.getRequestDispatcher("/WEB-INF/listBook.jsp").forward(request, response);

開發顯示全部書籍的jsp

    
   


    顯示全部的書籍




 
    
        書籍編號
        名稱
        做者
        詳細信息
        價格
    

      
        
            ${me.key}
            ${me.value.name}
            ${me.value.author}
            ${me.value.description}
            ${me.value.price}

購買操做

做爲購物車的案例,怎麼能沒有購買的操做呢?因而乎就增長購買的操做session

image.png

開發處理購買的Servlet

        //獲取獲得傳遞過來的id
String id = request.getParameter("bookid");

//把用戶想要買的書放到購物車上
//用戶不僅僅只有一個,要讓購物車上只爲當前的用戶服務,就須要用到會話跟蹤技術了
Cart cart = (Cart) request.getSession().getAttribute("cart");

//若是當前用戶尚未點擊過購買的商品,那麼是用戶的購物車是空的
if (cart == null) {
cart = new Cart();
request.getSession().setAttribute("cart", cart);
}

//調用BussinessService的方法,實現購買功能!
BusinessService businessService = new BusinessService();
businessService.buyBook(id, cart);

//跳轉到購物車顯示的頁面上
request.getRequestDispatcher("/listCart.jsp").forward(request, response);
  • 在咱們前面開發BusinessService時,是沒有buyBook()這個方法的!下面更新了BusinessService的代碼

    /*
   * 在購買書籍的時候,咱們發現須要將書籍添加到購物車上
   * 若是咱們直接在Servlet上使用Cart實體對象的addBook()和BookDao對象的find()方法,是能夠完成功能的
   *
   * 可是,這樣web層的程序就跟Dao層的耦合了,爲了代碼性的健壯性和解耦,咱們在BusinessService中對他倆進行封裝
   *
   * 因而有了buyBook()這個方法!
   * */

/*把用戶想買的書籍添加到當前用戶的購物車上*/
public void buyBook(String id, Cart cart) {

Book book = bookDao.find(id);
cart.addBook(book);

}

購物車的頁面

  • 初步把購物項的信息顯示出來

    %@ page contentType="text/html;charset=UTF-8" language="java" %>
    %@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
    
        購物車顯示頁面
    
    
    購物車顯示頁面
    
    %--empty函數是判斷集合中有沒有元素--%>
    %--若是購物車是沒有任何購物項的--%>
     
        您尚未購買過任何的書籍呀!
    
    
    %--若是購物車有購物項,就應該把購物項的信息顯示給用戶--%>
     
    
         
            
                書籍編號
                名稱
                數量
                小計
                操做
            
              
                
                    ${me.key}
                    ${me.value.book.name}
                    ${me.value.quantity}
                    ${me.value.price}
                     刪除
                
            
            
                  清空購物車
    
                 合計:
                ${cart.price}
  • 效果是這樣子的:

image.png


刪除購物車商品

image.png

想要刪除購物車中的商品,也很簡單,把刪除操做掛在超連接上,超連接指向DeleteCartServlet,並將想要刪除的書本的id帶過去(不將id帶過去,服務器哪知道你要刪除的是哪一個)

     刪除

開發DeleteCartBook的Servlet

        //獲取獲得用戶想要刪除哪一個書本的id
String id = request.getParameter("bookid");

//獲取該用戶相對應的購物車對象
Cart cart = (Cart) request.getSession().getAttribute("cart");

try {
//刪除購物車的商品,也應該是在BusinessService中有的功能,因而乎又回到BusinessService中寫代碼
BusinessService businessService = new BusinessService();
businessService.deleteBook(id, cart);

//刪除購物車的商品後,也應該直接跳轉回去購物車的顯示頁面中
request.getRequestDispatcher("/WEB-INF/listCart.jsp").forward(request, response);


} catch (CartNotFoundException e) {
request.setAttribute("message", "購物車空了!");
request.getRequestDispatcher("/message.jsp").forward(request, response);

} catch (Exception e) {
e.printStackTrace();
request.setAttribute("message", "刪除中出現了異常~待會再試試唄!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
  • BusinessService又多了一個功能

    /*用戶要在購物車中刪除某個購物項*/
public void deleteBook(String id, Cart cart) throws CartNotFoundException {

//若是用戶是直接訪問DeleteCartBook的Servlet的,在session中是沒有cart這個屬性的!
//告訴用戶購物車是空的
if (cart == null) {
throw new CartNotFoundException("購物車爲空");
}

//把購物項移除出去集合就好了!
cart.getBookMap().remove(id);
}

效果:

image.png

多本一塊兒購買

從上面的gif咱們就能夠發現,若是我重複買一本書,須要一本一本地點!這樣會很是麻煩!

咱們要怎麼實現:用戶想要買多少本,購物車的數量就修改成多少本呢

在購物車上,數量的值改爲是輸入框

    <td><input type="text" name="quantity" value="${me.value.quantity}"></td>

效果:image.png

好的,如今咱們已經可以把數量隨本身想要多少本,就改爲是多少了。如今主要的問題就是,怎麼在改的同時,數據也及時地更新?

寫javascript代碼,讓輸入框的信息提交給服務器

咱們寫javascript的代碼,監控着輸入框的變更,若是有變更,就響應事件,將變更的數據傳遞給服務器,更新數據!

    <script type="text/javascript">

/*
       * @input 將輸入框自己填入(這樣能夠獲取獲得輸入框的值)
       * @id   將書本的id傳遞進來,告訴服務器是修改哪個購物項(書)
       * @oldValue 本來的值,若是用戶不想修改了,就修改成本來的值(下面會詢問用戶是否肯定修改)
       * */
function update(input,id,oldValue) {

//獲取獲得輸入框的數據
var quantity = input.value;

//詢問用戶是否真的修改
var b = window.confirm("你肯定修改嗎?");

//若是肯定修改,就跳轉到修改的Servlet上
if(b) {
window.location.href = "${pageContext.request.contextPath}/UpdateQuantity?bookid=" + id + "&quantity=" + quantity + "";
}else {

//若是不肯定修改,把輸入框的數據改爲是原來的
input.value = oldValue;
}
}
</script>

編寫UpdateQuantity的Servlet

        //獲取獲得用戶想要修改哪一本書的id和相對應的數量
String id = request.getParameter("bookid");
String quantity = request.getParameter("quantity");

//獲得當前用戶的購物車
Cart cart = (Cart) request.getSession().getAttribute("cart");


try {

//調用BusinessService的方法去修改對應的數據
BusinessService businessService = new BusinessService();
businessService.updateQuantity(id, cart, quantity);

//修改完再跳轉回去購物車的頁面中
request.getRequestDispatcher("/WEB-INF/listCart.jsp").forward(request, response);

} catch (CartNotFoundException e) {
e.printStackTrace();
request.setAttribute("message", "購物車是空的!");
request.getRequestDispatcher("message.jsp").forward(request, response);
}

BusinessService增添了updateQuantity()方法

    public void updateQuantity(String id, Cart cart, String quantity) throws CartNotFoundException {


//若是用戶是直接訪問DeleteCartBook的Servlet的,在session中是沒有cart這個屬性的!
//告訴用戶購物車是空的
if (cart == null) {
throw new CartNotFoundException("購物車爲空");
}


//經過書的id獲取獲得購物車的購物項,再修改購物項的數量便可!(由於書的id和獲取購物項的關鍵字是一致的!)
cart.getBookMap().get(id).setQuantity(Integer.parseInt(quantity));

}

清空購物車

清空購物車的作法和上面是相似的!也是首先經過javaScript代碼詢問用戶是否要清空,若是要清空就跳轉到相對應的Servlet中把購物車的數據清空了!

在清空購物車的連接上綁定事件

     
           清空購物車

javaScript代碼作邏輯判斷

        function clearCart() {

var b = window.confirm("你肯定要清空購物車嗎?");

//若是用戶肯定,就跳轉到相對應的Servlet上
if(b) {
return true;
}else {
return false;
}
}

編寫ClearCart代碼

        //獲得用戶相對應的購物車
Cart cart = (Cart) request.getSession().getAttribute("cart");

//調用相對應BusinessService的方法
BusinessService businessService = new BusinessService();

try {

//清空購物車【實際上就是清空購物車的Map集合中的元素】
businessService.clearCart(cart);

//返回給購物車顯示頁面
request.getRequestDispatcher("/WEB-INF/listCart.jsp").forward(request, response);

} catch (CartNotFoundException e) {
e.printStackTrace();
request.setAttribute("message", "購物車是空的!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
}

在BusinessService中添加清空購物車功能

    public void clearCart(Cart cart) throws CartNotFoundException {

//若是用戶是直接訪問DeleteCartBook的Servlet的,在session中是沒有cart這個屬性的!
//告訴用戶購物車是空的
if (cart == null) {
throw new CartNotFoundException("購物車爲空");
}

//清空全部的購物項
cart.getBookMap().clear();


}


總結
  1. 購物車的應該是一個以id做爲key,以購物項做爲value的一個Map集合。這樣設計的話,咱們在顯示商品的時候,就不會重複顯示同一種類型的商品了。

  2. 購物項表明着該商品,而且應該給予購物項 數量和價錢的屬性。購物項的價錢應該是數量*單價

  3. 購物車應該提供把商品添加到購物車的功能。固然啦,購物項表明着商品,因此首先要判斷該購物車是否有同類的商品,若是有,直接在購物項的數量上+1便可的。若是沒有,就設置該購物項的屬性,並把購物項添加到購物車中

  4. 購物車的總價就是全部購物項的總價

  5. 不管是增刪改查購物車的數據,其實就是操做這個集合


若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章的同窗,能夠關注微信公衆號:Java3y

相關文章
相關標籤/搜索