JSR-168是適合于portlet開發(fā)人員的java API集合。設(shè)計符合規(guī)范的JSR-168 portlet的原因有很多。可移植性就一個顯而易見的好處。根據(jù)規(guī)范編寫的代碼更容易在門戶服務(wù)器之間移動。多數(shù)基于Java的門戶服務(wù)器都支持JSR-168 portlet。
另一個好處是更易于聯(lián)合。當(dāng)portlet符合JSR-168規(guī)范時,通過Web Services for Remote Portlets (WSRP)生產(chǎn)者公開JSR-168 Portlet會更容易一些。WSRP提供了一個通過Web service聯(lián)合portlet內(nèi)容的標(biāo)準。JSR-168和WSRP 1.0 portlet功能是緊密耦合的。JSR-168 to WSRP portlet橋利用JSR-168的URL重寫API。本文將闡述開發(fā)JSR-168 portlet以便獲得可移植性的最佳實踐。
Java開發(fā)人員經(jīng)常在如下所示jsp中編寫圖像的URL:
<img src="http://www.QQread.com/<%= request.getContextPath()%>/images/logo.gif"/>
這在JSR-168 portlet中是不正確的。正確的方法是:
<img src="http://www.qqread.com/j2ee/<%= renderResponse.encodeURL(renderRequest.getContextPath()+"/images/logo.gif") %>"/>
encodeURL()方法可以采用完全路徑URI或者完全限定URL。完全路徑URI是最常用的。在使用JSR-168 portlet將資源嵌入Web application Archive (WAR)中時,可以使用此技術(shù)。在將圖像放置到單獨服務(wù)器上時,可以使用完全限定URL。專門為靜態(tài)內(nèi)容提供服務(wù)的緩存服務(wù)器就是一個示例,它卸掉來自門戶服務(wù)器的通信量。盡管可以通過對完全限定URL使用encodeURL()來引用portlet以外的內(nèi)容,但應(yīng)該只在無法通過客戶機訪問資源時這樣做。如果客戶機可以直接瀏覽資源,則無需對URL使用encodeURL()。例如,如果有一臺Web服務(wù)器,可用該服務(wù)器獲得門戶用戶無法直接瀏覽的防火墻內(nèi)的靜態(tài)內(nèi)容,則需要調(diào)用encodeURL()。如果這些內(nèi)容在防火墻之外,并且門戶用戶可以直接瀏覽到Web服務(wù)器,則無需調(diào)用encodeURL()。
傳入RenderRequest的encodeUrl()方法中的URL在調(diào)用該方法之前必須是完整的。在調(diào)用該方法之后,無法添加URL的某些部分。例如,如果想從XSLT轉(zhuǎn)換中生成一個URL轉(zhuǎn)換,則不能將已編碼的基本URL(http://foo.com/)作為參數(shù)傳遞,并將路徑(pages/bar.jsp)附加到該轉(zhuǎn)換中的已編碼基本URL中。
以下調(diào)用演示了將URL編碼到圖像中的正確方式:
<@= renderResponse.encodeURL(renderRequest.getContextPath()+"/images/logo.gif")@>
它使用一個.portal文件在BEA WebLogic Portal 9.2中生成以下Html片段:
<img src="http://localhost:7001/PortalWebApp/images/logo.gif;PORTAL_TAU=W3f6FbmLLcgZq9Fpv1JHLs5rrJG8Lgj2nnDVJqdfShhRGFnsqCKZ!-545815275"/>
以下調(diào)用是不正確的。URL并不指向想要的資源。
<@= renderResponse.encodeURL(renderRequest.getContextPath()+ "/images/")+"logo.gif"@>
它使用.portal文件在WebLogic Portal 9.2中生成以下HTML文件:
<img src="http://localhost:7001/PortalWebApp/images/;
PORTAL_TAU=W3f6FbmLLcgZq9Fpv1JHLs5rrJG8Lgj2nnDVJqdfShhRGFnsqCKZ!-545815275logo.gif"/>
假設(shè)您想使用portlet中的javascript驗證用戶輸入。以下Javascript功能可能很有用:
<script>function validate(foo) { if (foo.bar.value=="") { return false; } return true;}</script>
同一頁面中的其他portlet可能也有一個命名為validate()的具有不同邏輯的JavaScript方法。門戶框架本身可能使用JavaScript方法。這個問題的解決方法是使用客戶端腳本中的名稱空間方法和頂層變量。<portlet:namespace/>標(biāo)記將為每個portlet生成一個惟一標(biāo)識符。第一步是通過taglib directive將標(biāo)記庫包含在JSP中。
<%@taglib uri="http://java.sun.com/portlet"腳本中的validate()方法可以對標(biāo)記加以區(qū)分。
<script>function validate<portlet:namespace/>(foo) { if (foo.bar.value=="") { return false; } return true;}</script>以下是調(diào)用帶名稱空間的JavaScript方法的方式:
<form action="http://www.somesite.org/servlet"method="GET" onsubmit="return validate<portlet:namespace/>(this);"><label for="bar">Text(required): </label><input type="text" name="bar" id="bar"></form>進入討論組討論。4. 確保引用Portlet資源的內(nèi)聯(lián)客戶端腳本符合規(guī)范
客戶端腳本常常引用外部資源(如圖像、電影和外部頁面)來增強用戶界面。常見的示例是預(yù)先加載圖像以使交換圖像更有效的JavaScript。以下是一個示例:
<script>function preloadImages(){ var menuImage = new Image(); menuImage.src = "images/icon.gif"; var menuImageDark=new Image(); menuImageDark.src = "images/icon.gif";}</script>客戶端腳本中的URL必須根據(jù)JSR-168規(guī)范進行重寫。這些腳本必須在JSP或JSP-168 portlet類中,以便調(diào)用重寫API的URL。它們不能在單獨的JavaScript (.js)文件中。以下是一個包含URL重寫的適當(dāng)名稱空間腳本在JSR-168 portlet中看起來的樣子:
<script>function <portlet:namespace/>preloadImages(){ var menuImage = new Image(); menuImage.src = "<%=renderResponse.encodeURL(renderRequest.getContextPath()+ "images/icon.gif")%>"; var menuImageDark= new Image(); menuImageDark.src = "<%=renderResponse.encodeURL(renderRequest.getContextPath()+ "images/icon_dark.gif") %>";}</script>5. 總是為portlet響應(yīng)聲明一個內(nèi)容類型
根據(jù)JSR-168規(guī)范,“portlet必須使用RenderResponse接口的setContentType方法設(shè)置響應(yīng)的內(nèi)容類型”。沒有顯式設(shè)置其內(nèi)容類型的portlet仍然會成功獲得編譯。但WebLogic Portal不會執(zhí)行沒有設(shè)置其內(nèi)容類型的portlet。確保您的portlet設(shè)置了其內(nèi)容類型。
以下示例演示了一個正確設(shè)置其內(nèi)容類型的portlet:
public class MyPortlet extends GenericPortlet { public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { response.setContentType("text/html"); PrintWriter writer = response.getWriter(); writer.println("I set my content type!
"); }}此示例是不正確的,但仍將獲得編譯:
public class MyPortlet extends GenericPortlet { public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { // no content type set! PrintWriter writer = response.getWriter(); writer.println("I did NOT set my content type!
"); }}進入討論組討論。6. 不要從Portlet發(fā)送Cookie
根據(jù)JSR-168 portlet規(guī)范,在HttpServletResponse上調(diào)用addCookie()實際上不會設(shè)置一個cookie。允許設(shè)置cookie的portlet容器被打破。不要調(diào)用此方法。
如果您喜歡在用戶使用門戶的時候基于每位用戶持久存儲信息,那么可以將信息存儲為portlet會話中的一個屬性。如果您喜歡在用戶退出后持久存儲信息,那么可以將信息存儲到數(shù)據(jù)存儲庫(文件系統(tǒng)、數(shù)據(jù)庫、LDAP等)中。
7. 將業(yè)務(wù)邏輯從表示中分離出來
有經(jīng)驗的開發(fā)人員都知道模型查看器控制器框架類似于Struts或Beehive,可以使開發(fā)富Web應(yīng)用程序變得更容易。這同樣也適用于portlet。JSR-168并不是適用于平臺獨立portlet的惟一理想規(guī)范。WSRP portlet在實現(xiàn)標(biāo)準的門戶(包括非Java門戶)之間移動很方便。WebLogic Portal 可以通過WSRP公開Beehive和Struts portlet。如果需要將portlet部署為JSR-168 WAR,您仍然有一些選擇。將業(yè)務(wù)邏輯從JSR-168 portlet的表示邏輯中分離出來的最簡單方法是指派一個JavaServer Page (JSP)。portlet處理呈現(xiàn)方法(比如render()和doView())中的業(yè)務(wù)邏輯。portlet使用應(yīng)用程序級作用域或portlet作用域?qū)⑿畔鬟f給JSP。下面的示例將一個portlet請求指派給JSP,并傳遞portlet作用域中的一個字符串:
public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { response.setContentType("text/html"); request.setAttribute("foo","bar"); String jsp = "/pages/portal.jsp"; PortletContext ctx = getPortletContext(); PortletRequestDispatcher dispatcher = ctx.getRequestDispatcher(jsp); dispatcher.include(request, response);}到達JSP(上述示例中的jsp)的路徑值并不包括portlet的Web歸檔文件(WAR)的上下文路徑。
JSR-168的指派方法允許將業(yè)務(wù)邏輯與表示分離。不過,它們?nèi)狈VC框架的成熟度。
適用于JSR-168開發(fā)的框架包括:
- Spring Portlet MVC
- WebWork
- Struts Action 2
Struts Action 2是Struts和WebWork的組合,因此portlet代碼庫對現(xiàn)在而言幾乎是一樣的。這些框架簡化了復(fù)雜portlet的開發(fā)和維護。
結(jié)束語
遵守這些指導(dǎo)原則會使您的portlet符合JSR-168規(guī)范。遵守規(guī)范會使您的portlet在Java門戶服務(wù)器之間移動變得更容易。還會使利用WSRP聯(lián)合門戶內(nèi)容變得更容易。
參考資料
- Java Community Process JSR-168 主頁
- OASIS WSRP 主頁
- WebLogic Portal 8.1 中的 URL(中文版,Dev2Dev,2005年5月)
- 利用WebLogic Portal 8.1 SP3開發(fā)Java Portlets(中文版,Dev2Dev,2004年8月)
作者簡介
Drew VarnerDrew Varner 是一名在BEA Federal Professional Services方面具有豐富實踐經(jīng)驗的高級首席顧問。在過去兩年中,他的工作是處理實現(xiàn)方面的防御和智能代理,包括JSR-168和WSRP門戶技術(shù)。進入討論組討論。(出處:http://m.survivalescaperooms.com)
學(xué)習(xí)交流熱門圖片猜你喜歡的新聞新聞熱點
2019-10-23 09:17:052019-10-21 09:20:022019-10-21 09:00:122019-09-26 08:57:122019-09-25 08:46:362019-09-25 08:15:43疑難解答
- 索泰發(fā)布一款GTX 1070 Mini迷你版本:小機箱
- AMD新旗艦顯卡輕松干翻NVIDIA 有幾個點我們
- i5 6500配什么顯卡最佳?i5 6500配1060顯卡可
- AMD新一批顯卡曝光:更便宜的14nm北極星
- A卡自修改BIOS安裝16.12.1 ReLive驅(qū)動教程
- 2016筆記本顯卡性能哪個好?筆記本顯卡天梯圖
- 2016顯卡性能怎么看好壞 顯卡天梯圖2016年1
- PS4 Pro顯卡解析:顯存帶寬相當(dāng)于標(biāo)準版PS4
- iGame 1050烈焰戰(zhàn)神U-2GD5版圖賞版:最美非
- EVGA FTW GTX 1080/1070顯卡存在嚴重問題: