Dreamweaver開(kāi)發(fā)JSP頁(yè)面
Macromedia Dreamweaver 為 HTML 提供了豐富的可視化編輯環(huán)境,這些功能是所有的 Web 開(kāi)發(fā)環(huán)境中都需要的。與其他工具相比,Dreamweaver 提供了更好的代碼編輯功能,包括為 Web 站點(diǎn)使用的宏,它們可以使用某種頁(yè)面語(yǔ)言,例如 ASP、ASP.Net、JSP、ColdFusion 和 PHP。擴(kuò)展宏讓您可以自動(dòng)進(jìn)行登錄,實(shí)現(xiàn)類(lèi)似何時(shí)隱藏的功能,自動(dòng)顯示結(jié)果集,創(chuàng)建客戶(hù)結(jié)果集等等。您可以編輯并添加自己的代碼宏。在不同的頁(yè)面之間可能存在一些可以共享的代碼(HTML 或腳本)。對(duì)于 JSP 的支持來(lái)說(shuō),Dreamweaver 為 JavaBeans 和 JSP 定制標(biāo)簽庫(kù)提供了完整的方法/標(biāo)簽。
Dreamweaver開(kāi)發(fā)JSP:視圖
讓我們開(kāi)始創(chuàng)建一個(gè)視圖來(lái)顯示所有的書(shū)籍。首先在 Server Behaviors 中為 JSP 添加一個(gè) RecordSet,并選擇希望在該表中顯示哪個(gè)表以及該表中的哪些列:
圖 2. Recordset 對(duì)話框
您可以看到我們已經(jīng)選擇從數(shù)據(jù)庫(kù)的 Books 表中顯示 Title、Authors 和 Publisher 字段;我們還會(huì)根據(jù) Title 字段,對(duì)結(jié)果進(jìn)行排序。在完成這個(gè)步驟之后,就可以將這些字段從 Bindings 窗口拖動(dòng)到 Web 頁(yè)面上:
圖 3. Bindings 窗口
由于我們正在創(chuàng)建一個(gè)視圖,應(yīng)該創(chuàng)建一個(gè)表來(lái)顯示文檔中的每一行的內(nèi)容:
圖 4. Categories 視圖
注意,該視圖中有幾個(gè)“Repeat”指示器,并且高亮顯示了表中的某一行,指出這是一個(gè) Repeating Region。這就是 Dreamweaver 的顯示 RecordSet 的方式,它通過(guò)循環(huán)遍歷記錄并重復(fù) HTML 部分的內(nèi)容來(lái)顯示 RecordSet。您也可以指定在 Repeat Region 對(duì)話框中顯示多少條記錄:
圖 5. Repeat Region 對(duì)話框
最后,您可以在該頁(yè)面中為結(jié)果添加一個(gè)導(dǎo)航條。雖然我們可以使用一個(gè)文本或圖形形式的導(dǎo)航條,但是為了簡(jiǎn)便起見(jiàn),此處我們將使用一個(gè)文本導(dǎo)航條:
圖 6. 導(dǎo)航條
現(xiàn)在我們可以看到在 Web 瀏覽器中顯示這個(gè)頁(yè)面時(shí)的樣子:
圖 7. Web 頁(yè)面
注意,如果您現(xiàn)在在第一個(gè)頁(yè)面中,那么導(dǎo)航條隱藏 Prev/First 部分。這個(gè)導(dǎo)航條還知道如何根據(jù)結(jié)果進(jìn)行分頁(yè)。由于您的重復(fù)字段被設(shè)置為一次只顯示 10 個(gè)結(jié)果,因此當(dāng)您單擊 Next 時(shí),這個(gè)導(dǎo)航條就會(huì)顯示下 10 條結(jié)果。當(dāng)您在最后一個(gè)頁(yè)面中時(shí),它還會(huì)隱藏導(dǎo)航條中的 Next/Last 部分。
Dreamweaver開(kāi)發(fā)JSP:用戶(hù)身份驗(yàn)證
要支持 Notes 中那種對(duì)書(shū)籍進(jìn)行編輯或分類(lèi)的功能,還需要提供一個(gè)單獨(dú)的 Web UI。然而,首先需要?jiǎng)?chuàng)建一個(gè)登錄頁(yè)面,因?yàn)槲覀儾⒉幌M總€(gè)用戶(hù)都可以修改書(shū)籍的類(lèi)別??梢栽陧?yè)面中放上幾個(gè)登錄字段來(lái)實(shí)現(xiàn)這種功能,如果登錄失效,就顯示一條錯(cuò)誤消息:
圖 8. 無(wú)效的登錄界面
您可以通過(guò)創(chuàng)建一個(gè)表單區(qū)域來(lái)實(shí)現(xiàn)這種功能,然后添加一個(gè)包含字段和字段標(biāo)簽的表。矩形的紅色區(qū)域是表單的邊界。表單操作被設(shè)置為跳回這個(gè)登錄頁(yè)面,因此必須添加一些代碼來(lái)處理實(shí)際的登錄操作。我們已經(jīng)添加了一條消息( JSP 圖標(biāo)邊上的文本)來(lái)顯示登錄失敗的用戶(hù)信息。
接下來(lái)我們要向這個(gè)頁(yè)面中添加一個(gè) Login Server Behavior:
圖 9. Log In User 對(duì)話框
正如您可以看到的,允許您指定使用數(shù)據(jù)庫(kù)中的哪個(gè)表來(lái)進(jìn)行身份驗(yàn)證,并允許您指定登錄用戶(hù)的訪問(wèn)級(jí)別(AccessLevel 字段)。您還可以指定用戶(hù)登錄成功或失敗之后將轉(zhuǎn)向哪個(gè)頁(yè)面。在登錄失敗時(shí),我們添加了一個(gè)查詢(xún)字符串參數(shù) “l(fā)f”。我們還添加了一些定制的代碼(這就是 JSP 圖標(biāo)指示的內(nèi)容)來(lái)處理這種功能:
- < % if (request.getParameter("lf") != null) { %>
- < p align="center">Invalid Login!< /p>
- < % } /* end request.getParameter(lf) != null */ %>
不幸的是,并不存在這種內(nèi)嵌的 Dreamweaver Server Behavior,這與視圖的導(dǎo)航條的隱藏功能不同。由于這個(gè)原因,您需要使用一個(gè)很好的 Java 工具來(lái)實(shí)現(xiàn)這種等效的自動(dòng)隱藏功能,除非您使用的是一個(gè)具有這種自動(dòng)隱藏功能支持的 JSP 定制標(biāo)簽庫(kù)。
Dreamweaver開(kāi)發(fā)JSP:訪問(wèn)控制
Dreamweaver 有一種顯示對(duì)特定頁(yè)面的訪問(wèn)的方便方法,除非用戶(hù)具有特定的訪問(wèn)權(quán)限,否則將不能訪問(wèn)特定頁(yè)面。Dreamweaver 對(duì)特定頁(yè)面的訪問(wèn)是通過(guò)向頁(yè)面中添加一個(gè) Restrict Access Server Behavior 實(shí)現(xiàn)的:
圖 10. Restrict Access to Page 對(duì)話框
在這種情況中,只有哪些在自己的登錄中具有管理員權(quán)限的用戶(hù)可以訪問(wèn)這個(gè)頁(yè)面。真正實(shí)現(xiàn)這種功能的代碼(在該頁(yè)面的可視化表示中,您看不到這些代碼)如下所示:
- < %
- // *** Restrict Access To Page: Grant or deny access to this page
- String MM_authorizedUsers="Administrator";
- String MM_authFailedURL="accessdenied.jsp";
- boolean MM_grantAccess=false;
- if (session.getValue("MM_Username") != null && !session.getValue
- ("MM_Username").equals("")) {
- if (false || (session.getValue("MM_UserAuthorization")=="") ||
- (MM_authorizedUsers.indexOf((String)session.getValue("MM_UserAuthorization"))
- >=0)) {
- MM_grantAccess = true;
- }
- }
- if (!MM_grantAccess) {
- String MM_qsChar = "?";
- if (MM_authFailedURL.indexOf("?") >= 0) MM_qsChar = "&";
- String MM_referrer = request.getRequestURI();
- if (request.getQueryString() != null) MM_referrerMM_referrer
- = MM_referrer + "?" + request.getQueryString();
- MM_authFailedURLMM_authFailedURL = MM_authFailedURL + MM_qsChar
- + "accessdenied=" + java.net.URLEncoder.encode(MM_referrer);
- response.sendRedirect(response.encodeRedirectURL(MM_authFailedURL));
- return;
- }
- %>
正如您可以看到的,它是與 Login Server Behavior 緊密地綁定在一起的。
Dreamweaver開(kāi)發(fā)JSP的缺點(diǎn)
Dreamweaver 為編輯頁(yè)面語(yǔ)言 Web 頁(yè)面提供了很好的環(huán)境(盡管它不能生成部署描述符)。不幸的是,異常行為會(huì)違反良好的 Web 架構(gòu)的一條規(guī)則:保持 UI 和邏輯分離。對(duì)于簡(jiǎn)單的站點(diǎn),可以這樣做,但是對(duì)于復(fù)雜而健壯的站點(diǎn)來(lái)說(shuō),必須保持二者是分離的。因?yàn)橐獙?shù)據(jù)庫(kù)訪問(wèn)操作和代碼直接加入 JSP 中,這使得對(duì) Web 站點(diǎn)的管理變得更加困難,除非您嚴(yán)格使用 Dreamweaver 開(kāi)發(fā)環(huán)境,或編寫(xiě)自己的操作。即使您繼續(xù)使用 Dreamweaver 環(huán)境,也會(huì)有很多問(wèn)題,因?yàn)槟赡軙?huì)更新 Dreamweaver 的版本, Server Behaviors 可能會(huì)發(fā)生變化,因此可能無(wú)法與以前的代碼匹配,這樣您就需要直接修改 JSP 代碼。
JSP 標(biāo)簽
JSP 定制標(biāo)簽和 JavaBeans 使得將用戶(hù)界面和業(yè)務(wù)邏輯分離成為可能。JSP 定制標(biāo)簽對(duì)于 Web 開(kāi)發(fā)人員來(lái)說(shuō)就像是定制的 HTML 標(biāo)簽。JavaServer Page Standard Tag Library(JSTL)是 JSP 1.3 中必不可少的一部分。JSTL 包含可以用來(lái)循環(huán)遍歷結(jié)果集并實(shí)現(xiàn) Hide-When 功能使用的標(biāo)簽。它還提供了 XML 處理和轉(zhuǎn)換標(biāo)簽的功能,并且可以引用與 JavaScript 類(lèi)似的對(duì)象。最后,它還提供了對(duì) JDBC 源的 SQL 訪問(wèn)功能,不過(guò)如果您試圖將 UI 和業(yè)務(wù)邏輯分隔開(kāi),就應(yīng)該避免使用這些標(biāo)簽。
舉例來(lái)說(shuō),如果登錄失敗,那么登錄頁(yè)面將顯示一條“invalid login”消息。然而,這需要知道如何編寫(xiě)一個(gè) Java if 表達(dá)式,以及要從什么對(duì)象中獲取查詢(xún)字符串參數(shù):
- < % if (request.getParameter("lf") != null) { %>
- < p align="center">Invalid Login!< /p>
- < % } /* end request.getParameter(lf) != null */ %>
使用 JSP 定制標(biāo)簽重新編寫(xiě)這段應(yīng)用程序,代碼如下:
- < c:if test="${!empty param.lf}">
- < p align="center">Invalid Login!< /p>
- < /c:if>
這就簡(jiǎn)單多了,也不必要求 Web 頁(yè)面的設(shè)計(jì)者必須了解 Java 的語(yǔ)法了。
所有的數(shù)據(jù)庫(kù)訪問(wèn)都應(yīng)該隱藏在 JavaBeans 中,以防止將 Web 站點(diǎn)的 UI 限制在數(shù)據(jù)庫(kù)中的數(shù)據(jù)上。降低數(shù)據(jù)的耦合度可以防止數(shù)據(jù)庫(kù)模式的變化,這會(huì)導(dǎo)致業(yè)務(wù)邏輯和用戶(hù)界面發(fā)生巨大的變化。如果處理適當(dāng),那么 JSP Web 頁(yè)面的設(shè)計(jì)者需要知道的惟一一件事情就是如何讀取 JavaBean 的值(這樣就可以在頁(yè)面中的適當(dāng)部分顯示)和要將頁(yè)面中的 POST 部分發(fā)往哪個(gè) URL(通常是一個(gè) servlet)。
【編輯推薦】