JSR-168 定義了 Portlet 的標準 API,遵循規範開發的 Portlet 具備跨入口網站伺服器可攜性,並易於透過 WSRP (Web Services for Remote Portlets) 進行內容聯合。本文彙整 7 項核心最佳實踐,助你開發符合規範、高可維護性的 Portlet。
錯誤寫法:<img src="<%= request.getContextPath() %>/images/logo.gif"/>
正確寫法:<img src="<%= renderResponse.encodeURL(renderRequest.getContextPath() + "/images/logo.gif") %>"/>
encodeURL() 會插入入口網站所需的上下文資訊 (如會話 ID、視窗狀態)。encodeURL() 輸入必須是完整路徑。錯誤:encodeURL(contextPath + "/images/") + "logo.gif" 會導致參數插在路徑中間,產生無效連結。正確:encodeURL(contextPath + "/images/logo.gif")。
同一頁面可能有多個 Portlet,JavaScript 函式名稱會衝突。使用 <portlet:namespace/> 產生唯一前綴。
<%@ taglib uri="https://java.sun.com/portlet" prefix="portlet" %>
<script>
function validate<portlet:namespace/>(form) { ... }
</script>
<form onsubmit="return validate<portlet:namespace/>(this);">...</form>
預載圖片等內嵌腳本中的 URL 必須經 encodeURL() 處理,且腳本必須寫在 JSP 或 Portlet 類別中,不可放在獨立 .js 檔 (無法呼叫 API)。
<script>
function <portlet:namespace/>preload() {
var img = new Image();
img.src = "<%= renderResponse.encodeURL(renderRequest.getContextPath() + "/images/icon.gif") %>";
}
</script>
規範要求 Portlet 呼叫 response.setContentType("text/html")。WebLogic Portal 等容器若未設定將拒絕執行。
public void doView(RenderRequest req, RenderResponse res) {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("Content type set correctly!");
}
規範明定 HttpServletResponse.addCookie() 在 Portlet 容器中無效。狀態保存請用 Portlet Session 屬性 (跨請求) 或持久化存儲 (跨會話)。
request.setAttribute(),再 dispatcher.include() 轉向 JSP。遵循這 7 項原則,可確保 Portlet 符合 JSR-168 規範,具備跨入口網站可攜性與 WSRP 聯合能力。