1. 程式人生 > >基礎Java Web: Servlet + Jsp + MySQL 商城Mall

基礎Java Web: Servlet + Jsp + MySQL 商城Mall

Mall

From ItCast Learning.Basic Web
專案地址:點選跳轉 路過可Star

Note

  1. 概要

    這是一個最基礎的Java EE Web專案——商城類

    專案內容可能過於淺顯,筆者是前段時間接觸框架時遇到了一些基礎問題,又重新拿起快速梳理的一遍。專案很容易上手,也適合複習基礎的Java Web知識。之前上學時也做過類似的專案,那個還是比這個美觀漂亮的多的,詳見 OnlineFoodCourt

    專案的文件及所有資源(含視訊教程)均在上文的連結中,可自取(另B站也可便捷觀看,傳送)。其中重要的文件和筆記,已經整理到專案下的reference

    中。

  2. 涉及技術點

    專案使用的是Servlet + JSP + MySQL + Redis 搭建的,使用Tomcat作為伺服器容器,沒有用到框架相關的任何知識。

    專案中通過既有的靜態網頁原型,改成了JSP檔案;通過JSP中的各種請求方式,向服務端傳送請求得到響應結果,最終渲染在JSP中返回給客戶端。主要是使用了 “ 介面 + 實現類 ” ,分層 “ Web + Servlet + Dao ” 兩種主體的設計思路,分模組進行開發設計。

    工作流(主):

    1545142711921)

    • 客戶端請求方式有:超連結、表單的action、便籤的click事件(Ajax非同步載入)等。預設:所有客戶端的請求都不直接請求jsp,而有Servlet轉向jsp響應
    • 服務端響應:轉發、重定向(重定向是二次請求,且不保留同一組的request/response)
    • 開發的步驟,其實就是上圖數字的順序。
  3. 模組

    案例被拆分成了前臺使用者和後臺管理兩大塊。

    前臺包括使用者模組商品模組購物車訂單,後臺有對應的分類管理商品管理訂單管理

    • 使用者模組:使用了Session標記使用者,主要是一個控制訪問許可權過濾,有些頁面如購物車和訂單等不登入無法檢視。使用Cookie來標記已登入的使用者,主要是實現記住登入或者勾選記住使用者名稱等。關於session和cookie的聯絡和區別可看我的另一篇筆記
    • 商品模組:從首頁的配置,動態獲取如“分類資訊”、“最新商品”、“熱門商品”等。其中如一些變化不頻繁的資訊如分類資訊,可使用redis快取控制,提升效能。 商品分類查詢時做了分頁處理,主要是載入了一個分類的類,控制頁面的輸出。
    • 購物車:抽取出購物車模型和購物項模型,這個在資料庫中並不存在。把購物項組成的購物車新增到session中。**注:**這裡並沒有把購物車和使用者的session聯絡起來,其實是可以處理的。
    • 訂單:根據需要抽離訂單和明細兩個模型。這裡要保證,提交訂單和訂單項的操作具有事務性。支付模型,呼叫第三方的外掛和工具即可(這個之前沒有做過)。
    • 後臺管理:同樣具有管理員的登入控制。Html中使用Dtree元件和frameWork元件構成。主要涉及到檔案上傳的問題,使用Commons-io等jar包完成。
    • 注:eclipse開發中,注意mysql配置的中文亂碼問題。
  4. 問題和工具

    在完成這個專案的時候,會遇到一些問題,這裡主要選擇幾個我之前不熟悉的地方記錄:

    • Redis: 一種資料儲存庫,主要以key-value的形式儲存資料,如Set,list格式。Redis使用記憶體管理,預設安裝啟動後擁有16個(0~15)個數據庫。支援高效快速的讀寫,所有操作都是原子性的。Redis支援訊息訂閱和釋出模式。事務:Redis的操作都是序列化的,擁有事務的最高隔離級別。 Redis中的資料可以進行落盤(快照或是日誌記錄形式)持久化。
    • BasicServlet:抽離出基礎的Servlet,通過引數控制使請求的反射執行不同方法多型。減少了重複性程式碼。Servlet的基本執行邏輯:init()----service()-----doGet/doPost()-----執行體。在最近基類的方法中尋找service方法,根據引數是get或post呼叫不同的方法(多型),重寫service後則直接執行其中的邏輯。
    • 響應資料:使用Request.setAttribute+EL 表示式,或AJax非同步載入(response.getWriter().println()),
      或者存在session中,或使用Redis------(如首頁的分類資訊)
    • Q1:
      在進行使用者註冊時,要控制事務性;如果郵件傳送失敗,則資料庫註冊的使用者需要回滾,不能新增到註冊但未啟用的賬戶資料表中,否則該郵箱無法進行重新註冊。
    • Q2:
      查詢物件時,需要將查詢到的資料通過反射機制,裝載到一個物件中。——可以使用工具類BeanUtils.populate方法自動裝配。———使用QueryRunner工具可以直接查詢DB的時候,返回裝配好的Bean。
    • Q3:
      EL表示式中,${}依次訪問的四個域為:pageContext, request.getAttribute, session, ServletContext,去找其中是否包含某個屬性或物件。使用 ${物件.屬性名},其實是呼叫了物件的get屬性名方法。
    • Q4:
      Servlet是一種容器,在執行中會被多個執行緒訪問同一份的引用(在Spring中可以配置單例和多例模式)。
    • Q5:
      Session的使用,例如購物車可以儲存麼?可以,使用session的監聽機制,在其失效前,獲取其中的儲存到資料庫中。
    • Q6:
      同一個表單下,如何設定不同的提交方式?不設定表單中的submit,使用不同標籤的click事件,JS非同步記載。
    • Q7:
      轉發和重定向?轉發只有一次請求,且只能到當前專案下。效能快。
      重定向有兩次請求,在位址列中看到的是最後一次的請求的資料,會丟失第一次的request。一般,在重複提交資料的時候,使用重定向,保證了資料的一致性。
    • Q8:
      在查詢某個使用者的所有訂單時,先查詢該使用者的所有訂單,根據這些訂單號,查詢每個訂單下的訂單明細項。由於明細關於產品的資訊在產品表中,則需要通過聯合查詢,給出滿足條件的集合。QueryRunner中使用了一個MapListHandler的類進行裝配。它是一個由map構成的list,每一個listitem代表結果的一行,一個map<string, object>表示表頭對應的值的鍵值對序列。
    • Q9:
      使用Redis時,一旦出現對Redis引用的資料做了DB的修改,則一定要注意修改Redis內容。
    • Q10:
      檔案上傳中,使用<input type=“file”>,form中要加上屬性enctype=“multipart/form-data”。此時不能再通過request.getParameter獲取。該方式獲取的是請求表單和請求體中的資料。 需要使用輸入流物件獲取。
      在上傳檔案中,一般存在檔案重名的覆蓋問題(使用UUID工具),和同檔案路徑下的訪問效能問題(使用多級多個路徑解決,如hashcode的字元路徑方式)
  5. 部署

    部署到某個Linux伺服器中,安裝相關的Tomcat/MySQL/Redis/等,主要是Tomcat容器必須有,其他的服務可以修改到對應安裝的地址到配置檔案中即可。

    將專案匯出成War包/Jar包,上傳到Tomcat 對應的WebApps檔案下,啟動對應的埠。第一次需要載入到容器中,比價慢,後續正常。

  6. 工具類

    • UUID 生產碼
    • BeanUtils 裝配Bean
    • 過濾器:編碼、登入等
    • BeanFactory 工廠解耦
    • JDBC、Jedis 資料庫
    • 支付,加密等
    • 上傳檔案 傳送郵件等