JavaWeb入门_模仿天猫整站Tmall_SSH实践项目
Tmall_SSH
技術棧 Struts2 + Hibernate + Spring + Jsp + Tomcat , 是 Java Web 入門非常好的練手項目
效果展示:
模仿天貓前臺
模仿天貓后臺
項目簡介
關聯項目
github - 天貓 JavaEE 項目
github - 天貓 SSH 項目
github - 天貓 SSM 項目
之前使用 JavaEE 整套技術來作為解決方案,實現模仿天貓網站的各種業務場景,現在開始使用框架技術,畢竟工作中還是要用框架。
本項目技術相對老舊,現在很少用 Struts2 了,但如果接手老項目的話還是要懂的,學習過程我們也可以認識到它們當時優秀的設計理念,
當時解決了哪些痛點,后面又是因為什么被新技術替代,這樣才能加深對 Java Web 整個平臺的理解,不虧。
項目用到的技術如下:
Java:Java SE基礎
前端:HTML,CSS, JavaScript,AJAX, JQuery, Bootstrap
J2EE:Tomcat, Servlet, JSP, Filter
框架: Hibernate,Struts,Spring,SSH整合
數據庫:MySQL
表結構
建表sql 已經放在 Github 項目的 /sql 文件夾下
| Category | 分類表 | 存放分類信息,如女裝,平板電視,沙發等 |
| Property | 屬性表 | 存放屬性信息,如顏色,重量,品牌,廠商,型號等 |
| Product | 產品表 | 存放產品信息,如LED40EC平板電視機,海爾EC6005熱水器 |
| PropertyValue | 屬性值表 | 存放屬性值信息,如重量是900g,顏色是粉紅色 |
| ProductImage | 產品圖片表 | 存放產品圖片信息,如產品頁顯示的5個圖片 |
| Review | 評論表 | 存放評論信息,如買回來的蠟燭很好用,么么噠 |
| User | 用戶表 | 存放用戶信息,如斬手狗,千手小粉紅 |
| Order | 訂單表 | 存放訂單信息,包括郵寄地址,電話號碼等信息 |
| OrderItem | 訂單項表 | 存放訂單項信息,包括購買產品種類,數量等 |
| Category-分類 | Product-產品 |
| Category-分類 | Property-屬性 |
| Property-屬性 | PropertyValue-屬性值 |
| Product-產品 | PropertyValue-屬性值 |
| Product-產品 | ProductImage-產品圖片 |
| Product-產品 | Review-評價 |
| User-用戶 | Order-訂單 |
| Product-產品 | OrderItem-訂單項 |
| User-用戶 | OrderItem-訂單項 |
| Order-訂單 | OrderItem-訂單項 |
| User-用戶 | User-評價 |
以上直接看可能暫時無法完全理解,結合后面具體到項目的業務流程就明白了。
開發流程
首先使用經典的 SSH 模式進行由淺入深地開發出第一個分類管理模塊 ,
然后分析這種方式的弊端,對其進行項目重構,重構這一塊可以學習到不少 Java 里的中高級處理手法,
使得框架更加緊湊,后續開發更加便利和高效率。
實體類設計
準備 Category 實體類,并用 Hibernate 注解標示其對應的表,字段等信息。
舉個例子,對于 分類 / category 的 實體類 和 表結構 設計如下:
DAOImpl 類設計
DAO 是 Data Access Object 的縮寫,專門用于進行數據庫訪問的操作。
DAOImpl 繼承了 HibernateTemplate,這是一個 Hibernate 框架提供的模板類,提供了各種各樣的 CRUD方法,滿足各種數據庫操作的需要。
重寫 HibernateTemplate 的 setSessionFactory() 方法, 以用于注入 SessionFactory ,
SessionFactory 是在 spring 的配置文件里面定義的 bean ,可以看到其配置了連接數據庫的數據源等信息,這樣 dao 操作的時候,就不必獲取對應的數據庫連接進行操作,
Spring 將數據源 ds 對象注入 SessionFactory ,sf 又被注入到 HibernateTemplate ,dao 繼承 HibernateTemplate 就可以直接操作數據庫了,非常簡便。
對比不使用 Spring+Hibernate 的情況,我們需要利用數據管理類 DBUtil 獲取 Connectoion ,
并在 dao 里面獲取對應的 Statement 分別實現 CURD 等方法,利用 JDBC 從數據庫取出數據,再構造成 bean 對象返回。
Service 類
設計 CategoryService 接口,用于提供業務方法 list() ,即查詢所有的分類。
public interface CategoryService{public List list(); }CategoryServiceImpl 實現了 CategoryService 接口,提供list()方法的具體實現,同時自動裝配(注入) 了 DAOImpl 的實例 dao ,
在 list() 方法中,通過 dao 獲取所有的分類對象。
Action 類
CategoryAction 類作為 MVC 設計模式中的控制層起作用。
配置文件
web.xml
這個web.xml做了3件事情
1.讓所有請求都進入 Struts2 的過濾器 StrutsPrepareAndExecuteFilter
2.對所有請求進行 UTF-8 編碼
3.指定Spring配置文件 applicationContext.xml 的位置
struts.xml
<struts><constant name="struts.i18n.encoding" value="UTF-8"></constant><constant name="struts.objectFactory" value="spring"/><package name="basicstruts" extends="struts-default"></package> </struts>applicationContext.xml
applicationContext 除了配置上述的 SessionFactory ,還要配置事務管理器
<!-- 配置事務管理器(聲明式的事務) --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sf"></property> </bean>訪問 jsp 顯示數據
Action 攜帶數據跳轉到 jsp ,作為視圖,擔當的角色是顯示數據,借助 JSTL 的 c:forEach 標簽遍歷從CategoryAction 的 list() 的傳遞過來的集合。
完整版的 listCategory.jsp 還包含4個公共文件,分別是 頭部,導航,行業,頁腳。
分類管理還有增加,編輯,修改,刪除,分頁,另外后臺其他管理頁面,前臺頁面。具體的需要瀏覽代碼,篇幅原因就不展開了。
思路流程圖
重構(這里非常精彩)
分類管理的 CURD 功能全部做好之后,代碼層面的問題開始逐漸浮現出來了,問題主要表現在 Service 層,和 Action 層。
Service層的問題
Service 層代碼如下:
首先看接口:CategoryService。 其聲明的方法基本上就是 CURD 和分頁。可以預見的是,在后續做產品管理,用戶管理,訂單管理等等,
也會有這么一個非常近似的 CURD 的接口,換句話說,這里是有做抽象和代碼重構的機會和價值的。
然后看實現類:CategoryServiceImpl。 CategoryServiceImpl本身其實就是個架子,真正起作用的是為其注入的DAO對象,
所以這個地方也是可以引入委派模式,使得代碼調用更加順暢。
Service 層的重構
Service層 的重構行為主要包括兩種角度
由于可以預見的在后續做產品管理,用戶管理,訂單管理等等,也會有這么一個非常近似的CURD的接口,
那么我們就做一個BaseService,里面就提供這些CRUD和分頁查詢的方法。
接著設計 BaseServiceImpl 類,其 CURD 關鍵方法都是調用的被注入的 dao 完成的,這樣就十分適合使用委派模式來重構這塊代碼。
不使用委派模式訪問數據庫都需要通過dao.XXX()來進行。 而委派重構之后,數據庫相關方法,不再需要通過dao,直接調用即可,代碼看上去更簡潔。
委派類 ServiceDelegateDAO
設計一個新的類,叫做 ServiceDelegateDAO ,在其中注入 dao ,然后讓對 dao 的每一個方法進行委派。
那么到底什么是委派呢? 如 ServiceDelegateDAO 類所示:
public void delete(Object entity) throws DataAccessException { dao.delete(entity); }
當調用 ServiceDelegateDAO 對象的 delete(Object entity) 的時候,其實就是委派給的 dao 的 delete(Object entity) 方法。
但是從調用者的角度來看,調用者只知道 ServiceDelegateDAO 這個類的 delete(Object entity) 方法,而意識不到 dao 的存在。
而 dao 繼承了 HibernateTemplate ,一共有一百多個方法,哈哈這么麻煩肯定有工具可以一鍵生成,
果然利用 idea 立馬就生成了所有委派方法,即快速又不會出錯,突然感覺好開心。
BaseServiceImpl
BaseServiceImpl 的構造器非常騷氣,BaseServiceImpl 的 clazz 對象需要引用實體類對象,這樣 CURD 方法中的 DetachedCriteria dc = DetachedCriteria.forClass(clazz); 才能獲取到對應的查詢對象。
所以這里利用反射,在構造方法中,借助異常處理和反射得到 Category.class 或者 Product.class 。 即要做到哪個類繼承了 BaseServiceImpl ,clazz 就對應哪個類對應的實體類對象。
首先要獲取是哪個類繼承了 BaseServiceImpl ,因為實例化子類,父類的構造方法一定會被調用,
所以在父類 BaseServiceImpl 里故意拋出一個異常,然后手動捕捉住它,
在其對應的 StackTrace 里的第二個(下標是1) 棧跟蹤元素 StackTraceElement ,即對應子類。
這樣我們就拿到了子類名稱 CategoryServiceImpl 或者 ProductServiceImpl,具體的在代碼注釋里了,寫的非常清楚。
這樣 CategoryService 就不需要自己聲明方法了,只需要繼承接口 BaseService 即可
CategoryServiceImpl 也不需要自己提供實現了,繼承 BaseServiceImpl 并實現接口 CategoryService 即可
這么做的好處主要在于:后續新功能開發的過程中,當需要新增加新的Service類的話,比如 PropertyService,無需從頭開發,
只需要繼承 BaseServiceImpl 并實現 PropertyService,那么其所需要CRUD一套方法都有了。
Action的問題
先看代碼
這樣的CategoryAction代碼完成功能是沒有問題的,但是問題恰恰在于,這樣一個本來是用于充當控制層(Controller)的類,需要集中應付太多的需求:
把所有的這些代碼,都放在一個類里面,這個類就會顯得繁雜,不易閱讀,不易維護。 所以這個地方也是很有代碼重構價值的。
Action 層的重構
目前 CategoryAction 存在的問題是一個類需要做太多的事情,顯的繁雜,影響閱讀和維護。 那么重構思路就是把不同的事情,放在專門的類進行處理,各司其職。
- 上傳專用 Action4Upload
這個類就專門用于處理圖片上傳,其他的事情一概不管 - 分頁專用 Action4Pagination
專門用于處理分頁,并且繼承上傳專用 Action4Upload - 對象和集合 Action4Pojo
用于提供實體對象以及實體對象集合的setter和getter.
setter用于接收注入
getter用于提供數據到JSP(VIEW)上 - 注入服務專用 Action4Service
Action4Service提供服務的注入
Action4Service 另外提供了一個方法 t2p() ,專門用于把對象指向對應的持久對象。
方法調用的最后結果就導致父類 Action4Pojo 中聲明的 pojo 本身是指向瞬時對象的,現在指向了持久對象(從數據庫中取出的對象)。
再定義返回頁面的 Action4Result 繼承 Action4Service ,專門進行返回頁面的定義
這樣
CategoryAction 繼承Action4Result, 于是就間接地繼承了 Action4Service,Action4Pojo,Action4Pagination,Action4Upload,
于是就通過繼承提供了各種相關的功能,CategoryAction 本身只需要專注于扮演控制器(Controller)本身就行了。這些工作對后面其他 Action 同樣適用,大大簡化了后續開發。
此外,后續還有針對 Service 的關系查詢重構,和Service 多條件查詢重構,具體的由于篇幅原因,請移步github 項目的地址
頁面展示
本篇博客所講不足整個項目的 1/10 ,有興趣的朋友請移步 github 項目的地址 。
參考
天貓SSH整站學習教程 里面除了本項目,還有 Java 基礎,前端,Tomcat 及其他中間件等教程, 可以注冊一個賬戶,能保存學習記錄。
轉載于:https://www.cnblogs.com/czwbig/p/9953893.html
總結
以上是生活随笔為你收集整理的JavaWeb入门_模仿天猫整站Tmall_SSH实践项目的全部內容,希望文章能夠幫你解決所遇到的問題。