Servlet+JSP+JavaBeanをベースに開発されたショッピングカート

巴扎黑
リリース: 2017-08-10 15:16:15
オリジナル
2202 人が閲覧しました

前回の記事では、最も一般的に使用されるユーザー ログイン登録プログラムを使用して Servlet+JSP+JavaBean 開発モデルを説明したため、Servlet+JSP+JavaBean (MVC) モデルについても予備的な理解ができました。次に、オンライン ショッピング用のショッピング カート プログラムを使用して、この開発モデルを確認してみましょう。

MVC アーキテクチャで Web プロジェクトを作成する

Eclipse で新しい day10 プロジェクトを作成し、プロジェクトに必要な開発パッケージ (jar パッケージ) をインポートし、プロジェクトに必要なパッケージを作成します Java 開発では、アーキテクチャ レベルがベースになります。パッケージがフォームに反映されます。
プロジェクトに必要な開発パッケージ(jarパッケージ):

シリアル番号 開発パッケージ名 説明
1 stl-1.2.jar jstlタグライブラリとEL式 型依存パッケージ

注: 前回の記事のユーザー ログイン登録プログラムとは異なり、このショッピング カート プログラムはデータベースを表すクラスを作成するため、他の jar パッケージを使用する必要はなく、stl-1.2.jar だけを使用します。
プロジェクトに必要なパッケージ:

シリアル番号 パッケージ名 説明 レベル
1 cn.itcast.DB stores代表的なデータベースクラス
2 cn.itcast.domain は、提供されるシステムのJavaBeanクラス(単純な属性と属性に対応するgetおよびsetメソッドのみを含み、特定の業務処理メソッドは含まれません)を格納します。 [データアクセス層]、[ビジネスロジック層]、[Web層]へは domain(ドメインモデル)層
3 cn.itcast.dao を使用して操作の実装クラスを格納しますデータベースにアクセスするためのインターフェース データアクセス層
4 cn.itcast.service には、処理系ビジネスインターフェース ビジネスロジック層
5 cn.itcastの実装クラスが格納されます。 web.controller は、サーブレットをシステムコントローラーとして保存します(リクエストを処理するサーブレット) Web層(プレゼンテーション層)
6 cn.itcast.web.UI は、ユーザーにユーザーインターフェースを提供します。厳密な MVC モードでは、JSP は保護されており、外部からの直接アクセスは禁止されているため、ユーザーが登録したい場合は、フォーム ページを取得し、サーブレットを使用して JSP に転送する必要があります。つまり、実際の開発では、一部のサーブレットはリクエストを処理するために使用され、一部のサーブレットはリクエストを受信して​​ JSP に転送してユーザーにユーザー インターフェイスを提供するために特別に使用されます Web 層 (プレゼンテーション層)
7 cn .itcast.utils は、システムの一般的なツールクラスを保存し、[データアクセス層]、[ビジネスロジック層]、および[Web層]に提供されて使用されます

上記は、このプロジェクトの実際の状況に基づいて作成されたパッケージです。プロジェクトのニーズに応じて、他のパッケージも作成する必要がある場合があります。
データベースを表すクラスを作成します:
これはオンライン書店プロジェクトであると仮定します。したがって、データベースに保存されている商品も書籍です。 cn.itcast.DB パッケージの下に DB クラスを作成します。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
DB クラスの具体的なコードは次のとおりです:

public class DB {    private static Map<String, Book> map = new LinkedHashMap<String, Book>();

    static {        map.put("1", new Book("1", "javaweb开发", "老张", 38, "一本好书"));        map.put("2", new Book("2", "jdbc开发", "老黎", 18, "一本好书"));        map.put("3", new Book("3", "ajax开发", "老佟", 328, "一本好书"));        map.put("4", new Book("4", "jbpm开发", "老毕", 58, "一本好书"));        map.put("5", new Book("5", "struts开发", "老方", 28, "一本好书"));        map.put("6", new Book("6", "spring开发", "老方", 98, "一本好书"));
    }    public static Map<String, Book> getAll() {        return map;
    }
}1234567891011121314151617
ログイン後にコピー

注: データベースを表すクラス - DB.java の作成方法については、Cookie を使用したセッション管理 を参照してください。
WEB-INF ディレクトリの下に jsp ディレクトリを作成します。jsp ディレクトリには、システムの保護された JSP ページが保存されます (ユーザーは、これらの保護された JSP ページにアクセスする場合にのみ、URL アドレスを介してアクセスできます)。 .itcast.web.UI パッケージの cn Servlet を通じてそれらを実行します。
作成されたプロジェクトのアーキテクチャは以下の図に示されています:
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート

階層化アーキテクチャのコード記述

階層化アーキテクチャのコードも[ドメインモデル層(ドメイン)]→[データアクセス層(dao,dao. impl) ] → [ビジネスロジック層(service、service.impl)] → [プレゼンテーション層(web.controller、web.UI、web.filter、web.listener)] → [ツールクラス(util)] → [テストクラス(junit) .test)】の順に記述します。

ドメイン層を開発する

cn.itcast.domain パッケージの下に Book クラスを作成します。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
Book クラスの具体的なコードは次のとおりです。

public class Book {    private String id;    private String name;    private String author;    private double price;    private String description;    public Book() {        super();        // TODO Auto-generated constructor stub
    }    public Book(String id, String name, String author, double price, String description) {        super();        this.id = id;        this.name = name;        this.author = author;        this.price = price;        this.description = description;
    }    public String getId() {        return id;
    }    public void setId(String id) {        this.id = id;
    }    public String getName() {        return name;
    }    public void setName(String name) {        this.name = name;
    }    public String getAuthor() {        return author;
    }    public void setAuthor(String author) {        this.author = author;
    }    public double getPrice() {        return price;
    }    public void setPrice(double price) {        this.price = price;
    }    public String getDescription() {        return description;
    }    public void setDescription(String description) {        this.description = description;
    }

}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
ログイン後にコピー

データ アクセス層 (dao、dao.impl) を開発します。

cn.itcast.dao パッケージの下に UserDao クラスを作成します。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
UserDao クラスの具体的なコードは次のとおりです:

public class BookDao {    public Map<String, Book> getAll() {        return DB.getAll();
    }    public Book find(String id) {        return DB.getAll().get(id);
    }

}1234567891011
ログイン後にコピー

サービス層を開発します (サービス層はすべてのビジネス サービスを Web 層に提供します)

新しいプロジェクトを初めて開発するとき、すべてのサービスの機能はわかりません。そのため、私たちは最初に考えやすい機能を開発し、ユーザーに扮してWebサイトのページを閲覧しながら、ユーザーが必要とする機能を確認し、それをプログラマーが開発します。その後、段階的に作業を進めてプロジェクト全体を統合します。
たとえば、このショッピング カート機能モジュールを最初に開発したとき、私が最初に考えたのは、すべての書籍をユーザーに表示し、書籍 ID に基づいて書籍情報をクエリすることでした。他の機能は期待していなかったので、これらの機能が完了するまで待って、フロントエンド ページに基づいてどのような機能が必要かを確認できます。
cn.itcast.service パッケージの下に BusinessService クラスを作成します。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
まず、次の 2 つのビジネス サービスを実装する BusinessService クラスを作成します。

  • すべての書籍をユーザーに表示する

  • 書籍IDに基づいて書籍情報をクエリする

具体的なコードは次のとおりです:

// 业务类,统一对web层提供所有服务public class BusinessService {    private BookDao dao = new BookDao();    public Map<String, Book> getAllBook() {        return dao.getAll();
    }    public Book findBook(String id) {        return dao.find(id);
    }
}12345678910111213
ログイン後にコピー

Webレイヤーを開発する

すべての書籍をユーザーに表示する機能を開発する

cn では、ListBookServlet が itcast.web.controller パッケージの下に作成され、すべての書籍をユーザーに表示します。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
ListBookServlet クラスの具体的なコードは次のとおりです:

// 获取所有书public class ListBookServlet extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {
        BusinessService service = new BusinessService();
        Map<String, Book> map = service.getAllBook();
        request.setAttribute("map", map);

        request.getRequestDispatcher("/WEB-INF/jsp/listbook.jsp").forward(request, response);

    }    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {
        doGet(request, response);
    }

}12345678910111213141516171819
ログイン後にコピー

/WEB-INF/jsp/ ディレクトリに JSP ページ listbook.jsp を記述して、すべての書籍をユーザーに表示します。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
WEB-INF ディレクトリにある JSP ページには、URL アドレスから直接アクセスすることはできません。開発中に、外部から直接アクセスされたくない機密 Web リソースがプロジェクト内にある場合は、外部からのアクセスを禁止できるように、これらの機密 Web リソースを WEB-INF ディレクトリに配置することを検討できます。 URL を通じて直接アクセスできます。
listbook.jsp ページのコードは次のとおりです:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>书籍列表页面</title></head><body style="text-align: center;">    <h1>书籍列表</h1>    <table width="70%" border="1" align="center">        <tr>            <td>书名</td>            <td>作者</td>            <td>售价</td>            <td>描述</td>            <td>操作</td>        </tr>        <c:forEach var="entry" items="${map }">            <tr>                <td>${entry.value.name }</td>                <td>${entry.value.author }</td>                <td>${entry.value.price }</td>                <td>${entry.value.description }</td>                <td>                    <a href="${pageContext.request.contextPath }/BuyServlet?id=${entry.key }" target="_blank">购买</a>                </td>            </tr>        </c:forEach>    </table></body></html>12345678910111213141516171819202122232425262728293031323334
ログイン後にコピー

Web サイトには一般的にホームページがあり、このプロジェクトでは、ホームページの Index.jsp に、ユーザーは 浏览书籍 ハイパーリンクをクリックして Web サイト上のすべての書籍を閲覧できます。
index.jsp ページのコードは次のとおりです:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>网站首页</title></head><body>    <a href="${pageContext.request.contextPath }/ListBookServlet">浏览书籍</a></body></html>123456789101112
ログイン後にコピー

これで、すべての書籍をユーザーに表示する機能の開発が完了しました。開発した関数をテストしてみましょう:
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート

开发购买书籍的功能

在现实中购买商品时,用户都是将商品放到购物车中,所以我们应该按照现实中的情况设计一个代表用户购物车的类——Cart.java。
现在再来思考一个问题:在设计代表用户购物车的Cart类时,应该使用private Book book字段(或属性)来代表用户所购买的商品吗?
答案显然不是。若是使用这样的字段,结果就是不可避免地在购物车中出现重复商品,即用户如果购买一本书多次,那么购物车中就出现一本书多次,显然在现实中这是不合理的。那么到底该怎么做呢?——为了避免在购物车里面出现重复商品,我们这时会设计一个专门的对象——CartItem(购物项,代表某个商品以及这个商品出现的次数)
在cn.itcast.domain包下创建一个CartItem类,用于代表某个商品,以及商品出现的次数(购物项)。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
CartItem类的具体代码如下:

// 用于代表某个商品,以及商品出现的次数(购物项)public class CartItem {    private Book book;    private int quantity;    private double price;    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;        this.price = this.book.getPrice() * this.quantity;
    }    public double getPrice() {        return price;
    }    public void setPrice(double price) {        this.price = price;
    }

}12345678910111213141516171819202122232425262728
ログイン後にコピー

在cn.itcast.domain包中创建一个代表用户购物车的Cart类。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
Cart类的具体代码如下:

// 代表用户的购物车public class Cart {    /*
     * 为了避免在购物车里面出现重复商品,
     * 我们这时会设计一个专门的对象——CartItem(购物项,代表某个商品以及这个商品出现的次数)
     */    private Map<String, CartItem> map = new LinkedHashMap<>();    private double price; // 记住购物车中的所有商品多少钱    public void add(Book book) {        // 看购物车中有没有,要添加的书对应的购物项
        CartItem item = map.get(book.getId());        if(item==null) {
            item = new CartItem();
            item.setBook(book);
            item.setQuantity(1);
            map.put(book.getId(), item);
        } else {
            item.setQuantity(item.getQuantity()+1);
        }
    }    public Map<String, CartItem> getMap() {        return map;
    }    public void setMap(Map<String, CartItem> map) {        this.map = map;
    }    public double getPrice() {        double totalprice = 0;        for(Map.Entry<String, CartItem> entry : map.entrySet()) {
            CartItem item = entry.getValue();
            totalprice += item.getPrice();
        }        this.price = totalprice;        return price;
    }    public void setPrice(double price) {        this.price = price;
    }

}12345678910111213141516171819202122232425262728293031323334353637383940414243
ログイン後にコピー

用户浏览网站首页时,会看到网站所有书籍,用户即可对自己感兴趣的书籍进行购买,点击购物超链接时,跳转到一个servlet对用户的请求进行处理。所以在cn.itcast.web.controller包中创建一个代表完成书籍购买的BuyServlet类。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
BuyServlet类的具体代码如下:

// 完成书籍购买@WebServlet("/BuyServlet")public class BuyServlet extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {

        String id = request.getParameter("id");
        BusinessService service = new BusinessService();
        Book book = service.findBook(id);        // 得到用户的购物车
        Cart cart = (Cart) request.getSession().getAttribute("cart");        // 用户第一次购买,为用户创建购物车        if(cart==null) {
            cart = new Cart();
            request.getSession().setAttribute("cart", cart);
        }        // 把书加到用户的购物车中,完成购买
        cart.add(book);        /* 
         * 浏览器重新访问地址:/WEB-INF/jsp/listcart.jsp
         * 但这个地址被保护起来,外面是无法直接访问的,
         * 要实现的话,会比较麻烦,需要先跳到servlet,然后再转到jsp。
         */        // response.sendRedirect("/WEB-INF/jsp/listcart.jsp");

        request.getRequestDispatcher("/WEB-INF/jsp/listcart.jsp").forward(request, response);
    }    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {
        doGet(request, response);
    }

}1234567891011121314151617181920212223242526272829303132333435363738
ログイン後にコピー

注意:显示购物车时,记住千万不要用请求转发,而应该使用重定向技术。若不是产生的后果可参考我的笔记Session——使用Session完成简单的购物功能。我上面的代码使用的是请求转发,这是不行的,读者要注意了啊!既然要使用重定向技术,下面这行代码可行吗?

response.sendRedirect("/WEB-INF/jsp/listcart.jsp");1
ログイン後にコピー

答案不言而喻,这是不行的。因为这是浏览器重新访问地址/WEB-INF/jsp/listcart.jsp,listcart.jsp页面是被保护起来了,外界是无法直接访问的。如果一定要实现的话,会比较麻烦,还需要先跳到一个servlet,然后再跳转到listcart.jsp。所以正规的做法是:BuyServlet类中使用重定向技术,即添加如下代码:

response.sendRedirect(request.getContextPath()+"/ListCartUIServlet");1
ログイン後にコピー

然后在cn.itcast.web.UI包下创建一个ListCartUIServlet类,专门用来接收请求之后转到jsp,给用户提供用户界面。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
ListCartUIServlet类的具体代码如下:

public class ListCartUIServlet extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {
        request.getRequestDispatcher("/WEB-INF/jsp/listcart.jsp").forward(request, response);
    }    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {
        doGet(request, response);
    }

}12345678910111213
ログイン後にコピー

这毕竟不是一个真实项目,所以不想把其搞得这么复杂哈!所以就干脆用了请求转发,但是读者一定要知道这还是不行的,要知道用重定向技术,怎么使用我也已经写的很明白了!
购物车显示页面listcart.jsp代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>购物车列表</title><script type="text/javascript">    function deleteitem(id) {        var b = window.confirm("您确认删除吗?");        if(b) {            // window代表当前浏览器窗口,location代表当前浏览器窗口的地址栏
            window.location.href = "${pageContext.request.contextPath }/DeleteItemServlet?id="+id;
        }
    }    function clearCart() {        var b = window.confirm("您确认清空吗?");        if(b) {
            window.location.href = "${pageContext.request.contextPath }/ClearCartServlet"
        }
    }    function changeQuantity(input, id, oldValue) {        var quantity = input.value; // 得到要修改的数量        /*
        // 检查用户输入的数量是不是一个数字
        if(isNaN(quantity)) {
            alert("请输入数字!!!");
            // 得到输入项原来的值
            input.value = oldValue;
            return;
        }
        */        // 检查用户输入的数量是不是一个正整数        if(quantity<0 || quantity!=parseInt(quantity)) {    // 1.1 != 1     parseInt("abc")返回NaN
            alert("请输入一个正整数!!!");
            input.value = oldValue;            return;
        }        var b = window.confirm("您确定把书的数量修改为"+quantity+"吗?")        if(b) {
            window.location.href = "${pageContext.request.contextPath }/ChangeQuantityServlet?id="+id+"&quantity="+quantity;
        }
    }</script></head><body style="text-align: center;">    <h1>购物车列表</h1>    <c:if test="${empty(cart.map) }"> <!-- cart.map.empty:map为空,没东西       el表达式的函数:empty()——检测map是否为null或"",若是则返回true   -->
        您没有购买任何商品!!!    </c:if>    <c:if test="${!empty(cart.map) }">    <table width="70%" border="1" align="center">        <tr>            <td>书名</td>            <td>作者</td>            <td>单价</td>            <td>数量</td>            <td>小计</td>            <td>操作</td>        </tr>        <c:forEach var="entry" items="${cart.map }">   <!-- entry<id, CartItem> -->            <tr>                <td>${entry.value.book.name }</td>                <td>${entry.value.book.author }</td>                <td>${entry.value.book.price }</td>                <td>                                                                                                <!-- this代表input输入项 -->              
                    <input type="text" name="quantity" value="${entry.value.quantity }" style="width: 35px" onchange="changeQuantity(this, ${entry.key }, ${entry.value.quantity })" />                </td>                <td>${entry.value.price }</td>                <td>                    <!-- javascript:void(0):去掉超链接的默认行为 -->                    <a href="javascript:void(0)" onclick="deleteitem(${entry.key })">删除</a>                </td>            </tr>        </c:forEach>        <tr>            <td colspan="3">总价</td>            <td colspan="2">${cart.price }元</td>            <td colspan="1">                <a href="javascript:void(0)" onclick="clearCart()">清空购物车</a>            </td>        </tr>    </table>    </c:if></body></html>123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
ログイン後にコピー

至此,用户购买书籍的功能就算是开发完成了!下面测试一下开发好的该功能:
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート

开发删除购物车中购物项的功能

编写实现如下业务服务的BusinessService类。

  • 删除购物车中购物项

此时BusinessService类的具体代码如下:

// 业务类,统一对web层提供所有服务public class BusinessService {    private BookDao dao = new BookDao();    public Map<String, Book> getAllBook() {        return dao.getAll();
    }    public Book findBook(String id) {        return dao.find(id);
    }    // 删除购物车中购物项    public void deleteCartItem(String id, Cart cart) {
        cart.getMap().remove(id);
    }

}12345678910111213141516171819
ログイン後にコピー

在cn.itcast.web.controller下创建一个DeleteItemServlet类。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
DeleteItemServlet类的具体代码如下:

public class DeleteItemServlet extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {

        String id = request.getParameter("id");
        Cart cart = (Cart) request.getSession().getAttribute("cart");

        BusinessService service = new BusinessService();
        service.deleteCartItem(id, cart);        // 删除成功,还是跳转到listcart.jsp页面
        request.getRequestDispatcher("/WEB-INF/jsp/listcart.jsp").forward(request, response);
    }    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {
        doGet(request, response);
    }

}123456789101112131415161718192021
ログイン後にコピー

注意:我上面的代码使用的是请求转发,这依然是不行的,读者要注意了啊!仍然要使用请求重定向,考虑到这毕竟不是一个真实项目,所以尽量不要搞得那么复杂,一切从简。
在购物车显示页面listcart.jsp中还要写入以下JavaScript代码:

<script type="text/javascript">    function deleteitem(id) {        var b = window.confirm("您确认删除吗?");        if(b) {            // window代表当前浏览器窗口,location代表当前浏览器窗口的地址栏
            window.location.href = "${pageContext.request.contextPath }/DeleteItemServlet?id="+id;
        }
    }</script>123456789
ログイン後にコピー

不然的话,用户手贱,不小心删除了所选的购物项,辛辛苦苦购买的商品又要重新购买,用户的感受肯定巨不爽,所以在用户不小心删除了所选的购物项时,还要问用户是否确认删除。只有用户点击确认按钮才会删除,这样对用户来说,体验会更好。
至此,删除购物车中购物项的功能就算是开发完成了!下面测试一下开发好的该功能:
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート

开发清空购物车的功能

编写实现如下业务服务的BusinessService类。

  • 清空购物车

编写对应的清空购物车的方法时,由于代表用户购物车的Cart类存在session中,是不是可以像下面这样写呢?

public void clearCart(HttpSession session) {    ...     }123
ログイン後にコピー

答:不可以。业务逻辑层用到Web层对象——session,业务逻辑层和Web层牢牢绑定在一起了,业务逻辑层离开Web层就跑不起来了,如果这样写,若要对业务层进行测试,需要把Web服务器起起来,传一个session进去,所以在各层之间传递的只能是JavaBean,不能让Web层的特殊对象侵入到业务逻辑层,污染业务逻辑层
此时BusinessService类的具体代码如下:

// 业务类,统一对web层提供所有服务public class BusinessService {    private BookDao dao = new BookDao();    public Map<String, Book> getAllBook() {        return dao.getAll();
    }    public Book findBook(String id) {        return dao.find(id);
    }    // 删除购物车中购物项    public void deleteCartItem(String id, Cart cart) {
        cart.getMap().remove(id);
    }    // 清空购物车    public void clearCart(Cart cart) {
        cart.getMap().clear();
    }

}123456789101112131415161718192021222324
ログイン後にコピー

在cn.itcast.web.controller包下创建一个ClearCartServlet类。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
ClearCartServlet类的具体代码如下:

public class ClearCartServlet extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {

        Cart cart = (Cart) request.getSession().getAttribute("cart");

        BusinessService service = new BusinessService();
        service.clearCart(cart);

        request.getRequestDispatcher("/WEB-INF/jsp/listcart.jsp").forward(request, response);
    }    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {
        doGet(request, response);
    }

}12345678910111213141516171819
ログイン後にコピー

注意:我上面的代码使用的是请求转发,这依然是不行的,读者要注意了啊!仍然要使用请求重定向,考虑到这毕竟不是一个真实项目,所以尽量不要搞得那么复杂,一切从简。
在购物车显示页面listcart.jsp中还要写入以下JavaScript代码:

<script type="text/javascript">    function clearCart() {        var b = window.confirm("您确认清空吗?");        if(b) {
            window.location.href = "${pageContext.request.contextPath }/ClearCartServlet";
        }
    }</script>12345678
ログイン後にコピー

不然的话,用户手贱,不小心清空了购物车,辛辛苦苦购买的商品又要重新购买,用户的感受肯定巨不爽,所以在用户不小心清空了购物车时,还要问用户是否确认清空。只有用户点击确认按钮才会清空,这样对用户来说,体验会更好。
还有一点要注意:如果用户清空了购物车,那么购物车显示页面不能没有任何显示,这也是对用户体验的一种折磨,明智的做法应该是给用户显示您没有购买任何商品!!!,这样用户体验会更好。那怎样判断用户有没有购买商品呢?——可使用el表达式的函数:empty(object),检测object对象是否为null或”“,若是则返回true。这样购物车显示页面listcart.jsp页面中的关键代码如下:

<h1>购物车列表</h1><c:if test="${empty(cart.map) }"> <!-- cart.map.empty:map为空,没东西       el表达式的函数:empty()——检测map是否为null或"",若是则返回true   -->
    您没有购买任何商品!!!</c:if><c:if test="${!empty(cart.map) }">
    ...</c:if>12345678
ログイン後にコピー

至此,清空购物车的功能就算是开发完成了!下面测试一下开发好的该功能:
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート

开发改变购物车某购物项数量的功能

在现实中的购物中,当用户购买一件商品时,发现还需要购买这件商品,比如数量为100,用户不可能点击这件商品100次,若是这样,那这样的购物网站倒闭1万亿遍了。所以一般来说用户只需要改变其数量即可,这时就需要用到<input>控件,而且用户要输入的数量要是一个正整数,不能是其他乱七八糟的东西。
编写实现如下业务服务的BusinessService类。

  • 改变购物车某购物项的数量

此时BusinessService类的具体代码如下:

// 业务类,统一对web层提供所有服务public class BusinessService {    private BookDao dao = new BookDao();    public Map<String, Book> getAllBook() {        return dao.getAll();
    }    public Book findBook(String id) {        return dao.find(id);
    }    // 删除购物车中购物项    public void deleteCartItem(String id, Cart cart) {
        cart.getMap().remove(id);
    }    // 清空购物车    public void clearCart(Cart cart) {
        cart.getMap().clear();
    }    // 改变购物车某购物项的数量    public void changeItemQuantity(String id, String quantity, Cart cart) {
        CartItem item = cart.getMap().get(id);
        item.setQuantity(Integer.parseInt(quantity));
    }

}123456789101112131415161718192021222324252627282930
ログイン後にコピー

在cn.itcast.web.controller中创建ChangeQuantityServlet类。
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート
ChangeQuantityServlet类的具体代码如下:

// 把购物车中的书修改为指定数量public class ChangeQuantityServlet extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {

        String id = request.getParameter("id");
        String quantity = request.getParameter("quantity");

        Cart cart = (Cart) request.getSession().getAttribute("cart");

        BusinessService service = new BusinessService();
        service.changeItemQuantity(id, quantity, cart);

        request.getRequestDispatcher("/WEB-INF/jsp/listcart.jsp").forward(request, response);
    }    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {
        doGet(request, response);
    }

}1234567891011121314151617181920212223
ログイン後にコピー

注意:我上面的代码使用的是请求转发,这依然是不行的,读者要注意了啊!仍然要使用请求重定向,考虑到这毕竟不是一个真实项目,所以尽量不要搞得那么复杂,一切从简。
在购物车显示页面listcart.jsp中还要写入以下JavaScript代码:

<script type="text/javascript">    function changeQuantity(input, id, oldValue) {        var quantity = input.value; // 得到要修改的数量        // 检查用户输入的数量是不是一个正整数        if(quantity<0 || quantity!=parseInt(quantity)) {    // 1.1 != 1     parseInt("abc")返回NaN
            alert("请输入一个正整数!!!");
            input.value = oldValue;            return;
        }        var b = window.confirm("您确定把书的数量修改为"+quantity+"吗?")        if(b) {
            window.location.href = "${pageContext.request.contextPath }/ChangeQuantityServlet?id="+id+"&quantity="+quantity;
        }
    }</script>1234567891011121314151617
ログイン後にコピー

完整的购物车显示页面listcart.jsp代码前面已经给出了,这里不再赘写。
至此,改变购物车某购物项数量的功能就算是开发完成了!下面测试一下开发好的该功能:
Servlet+JSP+JavaBeanをベースに開発されたショッピングカート

以上がServlet+JSP+JavaBeanをベースに開発されたショッピングカートの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!