Java EE 階段小項目(小型商城商品展示 + 購物車 + 下單 + 付款)

麻雀雖小,五臟俱全,UI 寫的比較 low,這個就不要太在意了

項目已經放在 Github 倉庫中:ShoppingMall

一、項目搭建

  1. 構建一個 Java Web 項目
  2. 數據庫 mysql 5.7 版本
  3. 開發工具 idea 2019, sqlyog
  4. 服務器版本 Tomcat 9.0.34
  5. 涉及到第三方 JAR 包:
    • mysql 驅動 5.1.44 版本以上
    • Tomcat 的所有 lib 包支持
    • jstl 1.2 標籤庫支持
    • 支付寶 SDK 提供的 jar 包
  6. 其他:
    • BootStrap 庫支持
    • Jquery 庫支持 (完成 ajax 操作)

二、商品界面展示

2.1 登錄界面

用戶需要輸入正確的賬號密碼,以及驗證碼,經後端校驗通過即可通過

  • 驗證碼由後端生成,驗證碼點擊圖片或者 文字 都可以通過 js 進行交換
  • 用戶名 ajax 校驗
  • 沒有編寫註冊功能,因爲我比較懶 hhhh
    在這裏插入圖片描述

2.2 商城主頁

  1. 用戶登錄成功就會進入該界面,用戶登錄信息經過 session 域進行保存
  2. 商品界面採用了 分頁處理
  3. 用戶可以選擇將商品添加至購物車 或者直接查詢購物車
    在這裏插入圖片描述
    在這裏插入圖片描述

2.3 購物車頁面

  1. 用戶選中項目可以對數量進行 添加 和 修改,修改的數據會通過 ajax 傳至後臺進行同步修改(這樣做並不是合理,所以有點小 bug)
  2. 商品如果不想要點擊刪除,會通過 ajax 進行刪除,然後頁面的 dom 也會刪除,但是有個小 個 bug,因爲沒有對數據進行重新查詢,所以,頁面會恢復原樣,但是數據庫的數據是已經刪除了該購物車信息了
  3. 因爲數據是動態渲染出來的,所以我使用 Jquery 完成購物車的 js 邏輯時,可能會有些小 bug, 所以我只用了一個產品進行購物
    在這裏插入圖片描述

2.4 確認支付環節

  1. 支付採用了支付寶的沙箱環境,我們需要配置一些信息到 沙箱頁面 和自己的本地環境即可完成沙箱環境接入

這個頁面其實可以直接跳過去的,不知道爲啥就寫進來了
在這裏插入圖片描述

2.5 真正的支付環境了

這裏可以看到前面購物車的賬單信息
在這裏插入圖片描述
這裏就和真真的支付沒啥關係了,但是千萬別傻乎乎的用自己的支付寶付錢,因爲支付寶的沙箱環境已經提供了虛擬賣家賬號 和 虛擬商家賬號了,在這裏我們可以快樂的充值,體驗一把有錢人的快樂,也可以下載對應的沙箱環境支付寶進行支付
在這裏插入圖片描述
和真實的支付環境基本有區別
在這裏插入圖片描述

三、後端重點

3.1 數據庫設計

這個 小小商城 只用到了三張表,總體邏輯也不是很複雜

3.1.1 用戶表 (user)

這是單獨的一張表
在這裏插入圖片描述

3.1.2 商品表 (product)

用於顯示對應的數據
在這裏插入圖片描述

3.1.3 購物車(Shopcart)

在這裏插入圖片描述

3.2 Java Web 後端邏輯難點分析

3.2.1 驗證碼實現

使用 java 的 2d 繪圖工具,繪製一張 png,我的代碼對驗證碼的繪製做了比較好的封裝,所以看起來比較舒服

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * 生成一個 6位數的驗證碼,並存放到 session 域中 valiCode
 * 並通過 response 返回
 * */
@WebServlet("/CodeServlet")
public class CodeServlet extends HttpServlet {
    private Random random = new Random();
    private int width = 80;//寬度
    private int height = 40;//高度
    private int fontsize = 20;//字體大小
    private String str = "0123456789abcdefghijklmnxnlopiiqusdakljnalwABCDEFGHIJKLMNOPQRSTUVWXYZ";

    //----------- 簡單版本 -------------
    private String randCode() { //生成 4個字符 隨機字符串代碼
        String code = "";
        for (int i=0; i<4; i++) {
            code +=str.charAt(random.nextInt(str.length()));
        }
        return code;
    }

    //------------ 生成至少四個字符的隨機字符串 --
    private String randCode1(int len) {
        if (len < 4) {
            len = 4;
        }
        //更改寬度
        width = 5 + fontsize*len ;
        String code = "";
        for (int i=0; i<len; i++) {
            code +=str.charAt(random.nextInt(str.length()));
        }
        return code;
    }

    //-------------  返回隨機字符串的顏色
    private Color randColor() {
        int r = random.nextInt(256);
        int g = random.nextInt(256);
        int b = random.nextInt(256);
        return new Color(r,g,b);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 設置 servlet 的顯示類型
        response.setContentType("image/png");
        // 2. 大致設置一個虛擬的驗證碼
        //1. 創建畫板
        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //2.創建畫筆
        Graphics2D pen = (Graphics2D)img.getGraphics();
        //3.生成隨機內容
        String code = randCode1(4); //生成 4位數驗證碼
        System.out.println(code);
        request.getSession().setAttribute("valiCode", code); //保存 code到 session,和後面的內容對應

        //4.繪製內容
        //	4.1 設置繪製區域
        pen.fillRect(0, 0, width, height);
        //	4.2設置字體
        pen.setFont(new Font("微軟雅黑",Font.BOLD,fontsize));
        //	4.3 按順序逐個繪製字符
        for (int i = 0;i<code.length();i++) {
            pen.setColor(randColor());//每個字符使用不同的顏色
            //繪製字符
            //code.charAt(i) 獲得的是單個字符,因此加一個 "" 使其變成字符串
            pen.drawString(code.charAt(i)+"", 5+i*fontsize,(fontsize + height)/2);
        }

        //	4.4 繪製噪音線  ------------------ 增加驗證碼難度
        for (int i = 0;i < 2;#### i++) {
            pen.setColor(randColor());//設置畫筆顏色
            pen.setStroke(new BasicStroke(3));//設置線條爲 3個像素
            //劃線的座標:x1,y1 x2,y2
            pen.drawLine(random.nextInt(width/2), random.nextInt(height), random.nextInt(width), random.nextInt(width));
        }
        //5.存爲圖片併發送
        ServletOutputStream out = response.getOutputStream();//數據通過 response 返回
        ImageIO.write(img, "png", out);
        out.flush();//緩存刷新
        out.close();//緩存關閉
    }

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

3.2.2 分頁邏輯實現

分頁邏輯實際就是對數據庫的數據進行分條查詢,選擇 mysql 數據庫,是因爲它有較好的分頁邏輯

  1. 我們需要一個參數 pageNo 表示當前是第幾頁的數據,這個我們需要從前端獲取,如果是第一次獲取,就得給一個默認值
  2. 再給一個 pageSize ,表示每頁固定展示的數據的條數
  3. 再給一個 count ,代表數據庫中數據的總記錄數,所以這裏需要進行聚合查詢的(select count(*) from xxx) 的到總記錄數
  4. 還沒完,還需要一個 pageCount,這個值代表當前頁面能顯示多少條數據,也是從後端數據庫進行獲取的

    給大家舉一個例子,假設我的數據庫裏有 11 條記錄,也就是第一次展示前 5條,當我們要看第二頁的時候就查詢第 6 到 10條數據,在翻頁就是查詢最後一頁的數據,因此這個 pageCount 是需要計算的,每次查詢出來的數據,告訴前端要顯示幾條數據

計算邏輯:

        int pageCount = 0;
        if (count%pageSize == 0) {
            pageCount = count/pageSize;
        } else {
            pageCount = count/pageSize+1;
        }
  1. 數據庫分頁查詢語句:select * from xxx limit pageSize*(pageNo-1), pageSize 這樣就可以做到上面的例子的邏輯

前端的分頁邏輯,採用 BootStrap 的分頁標籤 + jstl 標籤庫 共同實現分頁邏輯

        <nav>
            <ul id="pagination" class="pagination">
                <c:choose>
                    <c:when test="${pageNo>1}">
                        <li class="page-item"><a class="page-link" href="GetAllServlet?pageNo=${pageNo-1 }">上一頁</a></li>
                    </c:when>
                    <c:otherwise>
                        <li class="page-item"><a class="page-link" href="javascript:void(0);">上一頁</a></li>
                    </c:otherwise>
                </c:choose>
                &nbsp;&nbsp;&nbsp;&nbsp;
                <c:choose>
                    <c:when test="${pageNo<pageCount}">
                        <li class="page-item"><a class="page-link" href="GetAllServlet?pageNo=${pageNo+1 }">下一頁</a></li>
                    </c:when>
                    <c:otherwise>
                        <li class="page-item"><a class="page-link" href="javascript:void(0);">下一頁</a></li>
                    </c:otherwise>
                </c:choose>
            </ul>
        </nav>

3.2.3 支付寶沙箱支付環境接入

當時在接入的時候,也踩了比較多的坑,現在我把我的解決方案分享給大家(如果嫌麻煩,可以直接到 我的 ShoppingMall 倉庫下載這個 購物車的小 demo,裏面都是 配置好了的

  1. 下載 支付寶手機支付 API 的 SDK,我們是 Java 開發者,當然要下載 java 的 SDK:手機網站支付 SDK
  2. 然後可以大致預覽一下支付寶接入流程:接入流程
  3. 然後登陸支付寶開放平臺,填寫配置,不然後續就無法進行接入的相關工作
    在這裏插入圖片描述
  4. 閱讀沙箱環境支付接入流程:沙箱支付接入介紹
  5. 沙箱環境頁面介紹:
    在這裏插入圖片描述
  6. 然後是下載簽名工具:簽名工具使用

下載好就是這樣子的
在這裏插入圖片描述

因爲我們是個人開發者,沒有企業的資質,所以無法生成證書的,所以就默認點這個就可以了
在這裏插入圖片描述
然後將生成的公鑰添加到 沙箱環境的應用公鑰裏,就算是和支付寶環境接入完成了。
在這裏插入圖片描述
7. 然後是 java 代碼配置
將下載好的 sdk導入我們的項目
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

這裏替換上面兩個對應密鑰
在這裏插入圖片描述
到這裏就基本配置完成了,然後根據你的項目邏輯進行修改即可

  1. 差點忘記了,我們還需要將 SDK 提供的 jar 包導入進來
    在這裏插入圖片描述

四、總結

學到這裏 jsp 階段也算是告一段落了,目前是在學習 Vue 前端 + 後端 SpringBoot 交互的一些內容,目前進度,大愛 Vue,希望下次的項目能夠做的更加精彩,加油

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章