第三章:用戶(hù)管理功能【基于Servlet+JSP的圖書(shū)管理系統(tǒng)】

圖書(shū)管理系統(tǒng)

用戶(hù)管理
1. 查詢(xún)用戶(hù)信息
1.1 流程分析
我們需要展示的數(shù)據(jù)是sys_user
表結(jié)構(gòu)中的數(shù)據(jù)

然后對(duì)應(yīng)的實(shí)現(xiàn)邏輯

1.2 代碼結(jié)構(gòu)
清楚了我們要操作的數(shù)據(jù)。我們就可以來(lái)創(chuàng)建相關(guān)的代碼。整個(gè)項(xiàng)目的結(jié)構(gòu)我們分為com.boge.sys
和com.boge.book
兩個(gè)模塊。

然后創(chuàng)建SysUser
實(shí)體對(duì)象
我們?cè)谶@塊使用了lombok
來(lái)簡(jiǎn)化實(shí)體的定義。這塊需要添加對(duì)應(yīng)的依賴(lài)
???
然后在idea中我們需要添加lombok的插件

然后添加Dao
的接口定義和對(duì)應(yīng)的實(shí)現(xiàn)
1.3 DBUtils封裝
定義的Dao的實(shí)現(xiàn)類(lèi)。然后我們就需要通過(guò)JDBC來(lái)實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)表結(jié)構(gòu)中數(shù)據(jù)的CRUD
操作。為了簡(jiǎn)化操作我們通過(guò)Apache Dbutils
來(lái)實(shí)現(xiàn)。那么我們定義一個(gè)公共的MyDbUtils
工具類(lèi)。
然后就可以在UserDaoImpl
中通過(guò)我們提供的工具類(lèi)來(lái)完成數(shù)據(jù)庫(kù)的操作操作了
然后通過(guò)測(cè)試代碼完成查詢(xún)操作,看到如下結(jié)果表示成功

1.4 service
service這塊我們同樣的需要定義相關(guān)的接口和實(shí)現(xiàn)類(lèi)
1.5 Servlet
servlet的作用是接口瀏覽器傳遞的請(qǐng)求。然后根據(jù)service的處理把相關(guān)的結(jié)果響應(yīng)給瀏覽器。我們基于Servlet的規(guī)范來(lái)創(chuàng)建對(duì)應(yīng)的Servlet。那么Servlet需要繼承 HttpServlet
然后我們重寫(xiě)對(duì)應(yīng)的doGet
和doPost
方法。
1.6 頁(yè)面展示
數(shù)據(jù)展示頁(yè)面我們通過(guò)sys/user/list.jsp
來(lái)實(shí)現(xiàn)。注意我們需要調(diào)整web.xml
中的版本信息。

EL表達(dá)式?jīng)]有被識(shí)別,我們需要更新web.xml
中的信息
然后我們通過(guò)jstl
標(biāo)簽來(lái)實(shí)現(xiàn)數(shù)據(jù)的呈現(xiàn)。
然后對(duì)應(yīng)效果如下:

把sys/user/list.jsp
整合到系統(tǒng)的main.jsp
頁(yè)面中。也就是在我們整體的菜單中點(diǎn)擊用戶(hù)管理
需要展示list.jsp
中的數(shù)據(jù)。

然后我們需要在sys/user/list.jsp
中使用bootstrap
的樣式要調(diào)整數(shù)據(jù)的展示。最終的效果如下:

2. 添加用戶(hù)信息
2.1 后端邏輯處理
我們先實(shí)現(xiàn)了后端的用戶(hù)數(shù)據(jù)添加的邏輯。Dao的實(shí)現(xiàn)
然后是service的處理
然后是Servlet的處理,在Servlet中需要處理的請(qǐng)求很多。所以我們通過(guò)action來(lái)識(shí)別
2.2 前端表單處理
然后我們就需要來(lái)處理下前端頁(yè)面的表單邏輯。首先是點(diǎn)擊添加按鈕需要跳轉(zhuǎn)到添加數(shù)據(jù)的頁(yè)面。

然后我們?cè)趗serServlet中需要添加跳轉(zhuǎn)的邏輯處理

然后添加addOrUpdate.jsp
頁(yè)面。在頁(yè)面中添加數(shù)據(jù)的表單信息。具體如下:

數(shù)據(jù)提交的地址為/sys/userServlet?action=saveOrUpdate
提交成功后數(shù)據(jù)出現(xiàn)亂碼問(wèn)題。

2.3 中文亂碼
針對(duì)于客戶(hù)端提交數(shù)據(jù)到服務(wù)器涉及到中文的情況下。因?yàn)榫幋a不一致的情況會(huì)出現(xiàn)中文亂碼問(wèn)題。我們對(duì)應(yīng)的解決方案如下:

針對(duì)上面表單提交數(shù)據(jù)亂碼的問(wèn)題。

我們?cè)偬砑訑?shù)據(jù)的時(shí)候就沒(méi)有出現(xiàn)亂碼了

為了對(duì)編碼方式的統(tǒng)一處理。我們添加過(guò)濾器。然后在過(guò)濾器中統(tǒng)一做編碼問(wèn)題的解決
2.4 頭像功能
在系統(tǒng)用戶(hù)中我們需要維護(hù)用戶(hù)的頭像信息。這塊需要涉及到文件上傳和下載的操作。這塊也是非?;A(chǔ)的功能。正好在這塊介紹下在當(dāng)前項(xiàng)目中的應(yīng)用。在Servlet中我們需要操作文件上傳下載功能我們需要引入相關(guān)的依賴(lài)commons-fileupload
和commons-io
具體如下:
然后具體的上傳我們通過(guò)百度插件
來(lái)實(shí)現(xiàn)這塊的功能。http://fex.baidu.com/webuploader/
然后在表單中添加頭像的表單域信息

然后添加對(duì)應(yīng)的js
處理邏輯
有了這些操作后我們就可以看下訪問(wèn)的效果

在改插件中我們指定的上傳地址是/sys/uploadServlet
,然后我們需要?jiǎng)?chuàng)建該Servlet。
文件上傳成功后。Servlet中會(huì)返回上傳成功的文件的名稱(chēng)。我們會(huì)把這個(gè)名稱(chēng)綁定在表單中的一個(gè)隱藏屬性中。這樣在表單提交的時(shí)候會(huì)把名稱(chēng)存儲(chǔ)在數(shù)據(jù)庫(kù)中。

同時(shí)我們需要修改下保存用戶(hù)數(shù)據(jù)和查詢(xún)數(shù)據(jù)的邏輯。添加img
字段的處理
Dao中的處理調(diào)整
上傳成功后提交表單我們就會(huì)在數(shù)據(jù)庫(kù)中存儲(chǔ)圖片名稱(chēng)
最后在展示用戶(hù)信息的時(shí)候同時(shí)展示用戶(hù)的頭像信息。這時(shí)我們需要增加一個(gè)下載文件的Servlet
然后在list.jsp
中做相關(guān)的調(diào)整

展示效果:

3. BaseServlet
隨著我們的業(yè)務(wù)需求越來(lái)越多那么在Servlet中我們需要通過(guò)if語(yǔ)句來(lái)判斷各種請(qǐng)求。那么會(huì)造成doGet
或者doPost
方法中的代碼越來(lái)越復(fù)雜。不便于開(kāi)發(fā)。這時(shí)我們雖然可以通過(guò)方法抽取的方式來(lái)簡(jiǎn)化

雖然簡(jiǎn)化了doPost方法。但是還是需要很多的if語(yǔ)句來(lái)判斷。這時(shí)我們可以再進(jìn)一步的優(yōu)化,也就是我們約定瀏覽器提交的請(qǐng)求中攜帶的action
參數(shù)即使對(duì)應(yīng)的Servlet中要處理這個(gè)請(qǐng)求的方法的名稱(chēng)。這樣我們就可以通過(guò)反射方式來(lái)替換掉上面的if
語(yǔ)句處理的情況。徹底分離出各個(gè)處理請(qǐng)求的業(yè)務(wù)方法。
同時(shí)在BaseServlet
中又做了抽象的處理。聲明了增刪改查常用的相關(guān)的方法。這樣在具體的Servlet中我們就不用繁瑣的自己去創(chuàng)建相關(guān)的基礎(chǔ)放了。然后就可以改造UserServlet
中的處理。
最后注意調(diào)整之前用戶(hù)操作的相關(guān)請(qǐng)求的地址中的action
參數(shù)即可。
4. 更新用戶(hù)信息
用戶(hù)信息的更新操作,實(shí)現(xiàn)的邏輯是
點(diǎn)擊更新按鈕,傳遞用戶(hù)編號(hào)到后端
后端服務(wù)獲取到id查詢(xún)出對(duì)應(yīng)的用戶(hù)數(shù)據(jù)
跳轉(zhuǎn)到更新頁(yè)面。回寫(xiě)數(shù)據(jù)到表單中
提交更新的數(shù)據(jù)到服務(wù)
服務(wù)器獲取到更新的數(shù)據(jù)后更新到數(shù)據(jù)庫(kù)中
點(diǎn)擊更新按鈕傳遞編號(hào)到后端服務(wù)的實(shí)現(xiàn)


然后后端處理邏輯,Dao增加根據(jù)id查詢(xún)的方法
service同樣需要添加對(duì)應(yīng)的方法,然后就是Servlet中的處理
然后在表單中回寫(xiě)數(shù)據(jù)
需要注意的是更新數(shù)據(jù)需要在表單中攜帶id
,我們?cè)谏厦嫱ㄟ^(guò)<input type="hidden" name="id" value="${entity.id}">
實(shí)現(xiàn)。提交后。我們對(duì)應(yīng)的要修改Servlet中的邏輯

最后需要添加Dao中的更新方法
注意:更新功能沒(méi)有問(wèn)題。我們還需要檢查下添加功能是否受到影響!!!
5. 刪除用戶(hù)信息
刪除功能是一個(gè)非?;A(chǔ)的功能。在點(diǎn)擊刪除按鈕
的時(shí)候,我們需要給出提示框,防止用戶(hù)誤操作,這塊的提示框我們通過(guò)SweetAlert
來(lái)實(shí)現(xiàn)。效果如下:

引入sweetAlert
組件需要添加相關(guān)的css和js文件
添加對(duì)應(yīng)的點(diǎn)擊事件的處理方法
然后就是對(duì)應(yīng)的后端處理邏輯
6. 分頁(yè)查詢(xún)
6.1 分頁(yè)介紹
分頁(yè)功能在數(shù)據(jù)展示中是非常有必要的。原因有兩塊:
展示太多的數(shù)據(jù)用戶(hù)是否能夠消化
太多的數(shù)據(jù)我們的瀏覽器是否能夠支持(服務(wù)器是否能夠支持)

6.2 后端分頁(yè)處理
我們?cè)诤蠖颂幚聿樵?xún)操作的時(shí)候需要做分頁(yè)的處理。我們首先需要了解MySQL中的分頁(yè)語(yǔ)句。需要使用到limit
關(guān)鍵字
搞清楚了分頁(yè)SQL的實(shí)現(xiàn)那么就可以處理Dao中分頁(yè)邏輯的實(shí)現(xiàn)了,先在Dao接口中聲明分頁(yè)的方法
然后就是對(duì)應(yīng)的分頁(yè)查詢(xún)實(shí)現(xiàn)
可以通過(guò)main
方法來(lái)測(cè)試

然后針對(duì)分頁(yè)操作的相關(guān)數(shù)據(jù)比較多,我們可以自定義一個(gè)PageUtils
來(lái)封裝分頁(yè)相關(guān)的信息。具體如下:
然后在Servlet和Service中實(shí)現(xiàn)分頁(yè)處理。同時(shí)調(diào)整Dao中的實(shí)現(xiàn)代碼
然后對(duì)應(yīng)的Service中既有查詢(xún)分頁(yè)數(shù)據(jù)也得查詢(xún)總的記錄數(shù)
然后在Dao中提供這兩個(gè)數(shù)據(jù)操作的支持
然后就可以測(cè)試分頁(yè)的數(shù)據(jù)了:

針對(duì)UserServlet
中查詢(xún)分頁(yè)信息的方法有很多分頁(yè)處理的邏輯造成整個(gè)方法顯得臃腫,不是很簡(jiǎn)潔針對(duì)這種情況我們可以把公共代碼提取到BaseServlet
中。
然后在業(yè)務(wù)代碼中只需要調(diào)用父類(lèi)中的方法即可:如下,代碼整個(gè)就非常直觀和簡(jiǎn)潔了。
6.3 前端分頁(yè)功能
前端分頁(yè)展示的效果如下:

首頁(yè)是下面的分頁(yè)條目。這塊我們是通過(guò)DataTables
插件中的分頁(yè)欄來(lái)實(shí)現(xiàn)的。
然后需要引入DataTabls
的樣式文件
綁定我們對(duì)應(yīng)的分頁(yè)的數(shù)據(jù)

然后處理動(dòng)態(tài)分頁(yè)中的數(shù)字頁(yè)。我們?cè)贒BUtils中定義getPageList
方法,提供對(duì)應(yīng)的分頁(yè)數(shù)字
對(duì)應(yīng)的還需要實(shí)現(xiàn)getTotalPage
方法的邏輯
有了這個(gè)方法的支持。對(duì)應(yīng)的動(dòng)態(tài)分頁(yè)數(shù)字就可以實(shí)現(xiàn)了
要實(shí)現(xiàn)具體的分頁(yè)功能。我們還需要提供提交數(shù)據(jù)的表單。這塊和關(guān)鍵字
查詢(xún)關(guān)聯(lián)起來(lái)
最后就是提供相關(guān)的js方法
搞定分頁(yè)功能,當(dāng)然我們還需要添加關(guān)鍵字查詢(xún)的邏輯
7. 帶條件查詢(xún)
在一個(gè)基礎(chǔ)功能模塊中。帶條件查詢(xún)的功能也是非常用必要的。而已是需要結(jié)合在分頁(yè)功能中的。在用戶(hù)管理中我們也需要來(lái)實(shí)現(xiàn)這塊的功能。在PageUtils
中定義看一個(gè)key的屬性。那么在查詢(xún)的表單中我們添加一個(gè)key的表單域。
然后修改PageUtils
中的邏輯。添加對(duì)key
的處理。注意這塊我們只需要在BaseServlet
中處理即可
最后在UserDaoImpl
中添加帶條件的查詢(xún)操作即可
具體效果如下:

把分頁(yè)的公共部分可以提取出來(lái)。在更目錄下創(chuàng)建一個(gè)common/commonPage.jsp
頁(yè)面
然后在/sys/user/list.jsp
中通過(guò)include
指令來(lái)引入這個(gè)分頁(yè)的公共頁(yè)面
這樣就能達(dá)到簡(jiǎn)化和減少冗余代碼的效果。