2006/11/17

Portlet JSR-168 Note

Portlet JSR-168 Note

************************
PLT.5 The Portlet Interface
PLT.5.1 Number of Portlet Instances
每個portlet container針對每一個portlet definition,只能產生一個object

PLT.5.2 Portlet Life Cycle
portlet的life cycle透過javax.portlet.Portlet裡的init, processAction, render, destory methods來處理

PLT.5.2.1 Loading and Instantiation
portlet container在啟動時或是portlet被呼叫時,負責loading and instantiating portlets

PLT.5.2.2 Initialization
container以implement javax.portlet.PortletConfig 的唯一物件,透過javax.portlet.Portlet裡的init初始化portlet,並提供定義裡的ResourceBundle。PortletConfigImpl也必須提供描述portlet runtime environment(context物件, implements java.portlet.PortletContext)的access介面

PLT.5.2.2.1 Error Conditions on Initialization
initiallization時,portlet可能會throw UnavailableException或PortletException,這時候就必須要呼叫portlet的destroy
在portlet初始化失敗後,可以再次重新嘗試初始化,但必須在等待一段時間之後
初始化時的RuntimeException要以PortletException的方式處理

PLT.5.2.2.2 Tools Considerations

PLT.5.2.3 Portlet Window
preferences objects是以定義中的初始值初始化,container要提供客製化preferences物件的機制
當portlet放入portal page中,就有一個配置的preferences object,portlet跟preferences object合在一起稱為portlet window,由container負責維護他們之間的關係
管理配置pref objects與產生portlet window的方式交由container implementation,也可提供進階功能,例如階層式管理pref objects

PLT.5.2.4 Request Handling
javax.portlet.Portlet定義了processAction, render兩個methods
當container呼叫portlet的processAction時,request會參考action request,當container呼叫render時,request會參考render request
通常client的request是由portlet產生的URL trigger,稱為portlet URLs,一個portlet URL會指向一個特定的portlet。portlet URL有兩種,action URLs 或 render URLs
當client request經由action URL被trigger時,container要先處理目標portlet的processAction,然後再處理其他portlet的render。當client request經由render URL被trigger時,container就執行所有portlet的render
如果portlet有caching功能,container可選擇不執行render,而使用cached content

PLT.5.2.4.1 Action Request
在處理action request時,portlet會以action request裡的參數更新自己的state
Portlet裡的processAction有兩個參數,ActionRequest, ActionResponse
ActionRequest提供access許多參數資訊的介面,action request, window state, portlet mode, portal context, portlet session, portlet preferences data
在處理actio request的時候,portlet可以讓container重導到某個特定的URL
portlet在處理action request時,會在ActionResponse中改變portlet mode與window state,portlet mode會影響render的結果

PLT.5.2.4.2 Render Request
Portlet的render有兩個參數,RenderRequest, RenderResponse
RenderRequest提供許多參數的存取介面,render request, window state, portlet mode, portal context, portlet session, portlet preferences data
portlet由RenderResponse的writer產生content,也可以交給servlet或jsp處理

PLT.5.2.4.2.1 GenericPortlet
render會set title(在定義中)並執行doDispatch
doDispatch幫忙根據portlet mode處理request,doView:處理VIEW, doEdit:處理EDIT, doHelp:處理HELP
如果portlet的window state為MINIMIZED,則render不會執行任何一個render methods

PLT.5.2.4.3 Multithreading Issues During Request Handling
container負責處理concurrent requests的問題,Portlet developer也要在processAction與render中處理concurrent的問題

PLT.5.2.4.4 Exceptions During Request Handling
portlet可能會throw PortletException, PortletSecurityException, UnavailableException
PortletException表示處理request時發生錯誤,container必須要停止繼續執行該portlet,但其他portlet還是要繼續處理render。
PortletSecurityException表示request因user沒有足夠的權限被中止
UnavailableException表示portlet暫時或永久不能處理request
RuntimeException的處理方式跟PortletException一樣

PLT.5.2.4.5 Thread Safety
request跟response object都不保證thread safe

PLT.5.2.5 End of Service
當container因記憶體不足或shutdown的時候,可呼叫destroy後結束portlet object


************************
PLT.6 Portlet Config
PLT.6.1 Initialization Parameters
PortletConfig的getInitParameterNames, getInitParameter會傳回portlet定義中的initialization parameter names/values

PLT.6.2 Portlet Resource Bundle
在定義中的裡有title, short-title, keywords
如果有定義com.foo.myApp.QuotePortlet,container必須要產生ResourceBundle提供大家使用,render method會使用PortletConfig裡的ResourceBundle取回ResourceBundle裡定義的title資料

************************
PLT.7 Portlet URLs
portlet需要產生參考到自身的portlet的URL,作為content的一部分
PLT.7.1 PortletURL
portlet會藉由RenderResponse裡的createActionURL與createRenderURL產生PortletURL介面的實作,createActionURL產生action URLs,createRenderURL產生render URLs
因為有些container會產生一些狀態碼放在URL上,portlet開發人員不應該自己寫form並使用HTTP GET method取得資料
portlet可以在PortletURL中加入自己的參數,setParameter與setParameters
container必須要 "x-www-form-urlencoded"對參數名字與值編碼,但developer不需要encode parameter names/values
ex: PortletURL url = response.createRenderURL();
url.setParameter("customer", "foo.com");
url.setParameter("show", "summary");
writer.print("Summary");

PLT.7.1.1 Including a Portlet Mode or a Window State
portlet URL 必須要包含portlet mode的參數,PortletURL裡有setWindowState, setPortletMode兩個methods
ex: PortletURL url = response.createActionURL();
url.setParameter("paymentMethod", "creaditCard");
url.setWindowState(WindowState.MAXIMIZED);
writer.print("< FORM METHOD=\"POST\" ACTION=\""+ url.toString()+"\" >");

portlet不能設定未定義的PortletMode,會產生PortletModeException
portlet不能設定未定義的WindowState,會產生WindowStateException

PLT.7.1.2 Portlet URL security
PortletURL.setSecure可指定為HTTPS or HTTP,如果未指定,則跟current request一樣


************************
PLT.8 Portlet Modes
VIEW, EDIT, HELP

PLT.8.1 VIEW Portlet Mode
Portlet一定要support VIEW mode,overriding doView

PLT.8.2 EDIT Portlet Mode
Portlet不一定要支援EDIT mode
overriding doEdit

PLT.8.3 HELP Portlet Mode
Portlet不一定要支援HELP mode
overriding doHelp

PLT.8.4 Custom Portlet Modes
Portal廠商可以自己定義自己的mode,要寫在定義檔裡的custom-portlet-mode裡面,在PLT.A裡面有建議提供的自訂Portlet Modes
ex:

Creates content for Cut and Paste
clipboard


Provides administration functions
config


PLT.8.5 GenericPortlet Render Handling
GenericPortlet實作的render method會將request dispatch到doView, doEdit, doHelp,如果Portlet提供自訂modes,則必須要override doDispatch

PLT.8.6 Defining Portlet Modes Support
ex:

text/html
edit
help
...


text/vnd.wap.wml
help
...


***********************
PLT.9 Window States
window state代表portal page上可填寫的content畫面空間大小
標準有三種window states: NORMAL, MAXIMIZED, MINIMIZED

PLT.9.1 NORMAL Window State
PLT.9.2 MAXIMIZED Window State
PLT.9.3 MINIMIZED Window State
PLT.9.4 Custom Window States
ex:

Occupies 50% of the portal page
half_page



*****************
PLT.10 Portlet Context
PortletContext定義了portlet執行中的時候,Portlet application中的portlet能做什麼事情,例如使用PortletContext,portlet能夠log events, obtain portlet application resources, set/store attributes for other portlets/servlets

PLT.10.1 Scope of the Portlet Context
在containter中PortletContext的實作instance只會有一個

PLT.10.2 Portlet Context functionality
透過PortletContext,能夠 access context initialization parameters, retrieve/store context attributes, obtain static resources, obtain a request dispatcher to include servlets/JSPs

PLT.10.3 Relationship with the Servlet Context
context-wide initialization parameters跟servlet context的一樣
context attributes跟servlet context一起共用,透過PortletContext跟ServletContext取得的initialization parameters會完全一樣
透過ServletContext跟PortletContext存取的attributes都一樣

??? PortletContext必須處理ServletContext中所提供的temporary working directory (Servlet spec 2.3 javax.servlet.context.tempdir)

PLT.10.4 Correspondence between ServletContext and PortletContext methods
PortletContext必須仿照ServletContext提供 getAttribute, getAttributeNames, getInitParameter, getInitParameterNames, getMimeType, getRealPath, getResource, getResourcePaths, getResourceAsStream, log, removeAttribute, setAttribute


*********************
PLT.11 Portlet Requests
PLT.11.1 PortletRequest Interface
PortletRequest提供ActionRequest與RenderRequest共用的功能

PLT.11.1.1 Request Parameters
如果portlet收到client端的request,URL必須要encode(PortletURL),request object的parameters必須要是"x-www-form-urlencoded" decoded
containter不能從action request傳遞參數給後續的render requests,如果portlet需要這樣作,則必須要在ActionRespponse裡的processAction中使用setRenderParameter or setRenderParameters

portlet不可以取得傳遞到別的portlet中的參數

取得參數的介面methods: getParameter, getParameterNames, getParameterValues, getParameterMap

PLT.11.1.2 Extra Request Parameters
containter可以在portlet URL上增加參數,幫助route/process request
以"javax.portlet."為prefix的參數,保留給container使用

PLT.11.1.3 Request Attributes
JSP/servlet透過PortletRequestDispatcher分享使用request attributes
PortletRequest可以set, obtain, remove參數,methods: getAttribute, getAttributeNames, setAttribute, removeAttribute

以"javax.portlet."為prefix的attributes,保留給container使用

PLT.11.1.4 Request Properties
HTTP client request裡的headers可透過 PortletRequest的getProperty, getProperties, getPropertyNames取得

PLT.11.1.5 Request Context Path
context path是portlet app被deploy時的路徑,path不能以"/"開頭,不能以"/"結尾

PLT.11.1.6 Security Attributes
PortletRequest裡的 getAuthType, getRemoteUser, getUserPrincipal, isUserInRole, isSecure

getAuthType: portal使用的authentication scheme, ex: BASIC_AUTH, DIGEST_AUTH, CERT_AUTH, FORM_AUTH,如果USER沒有authenicated,則getAuthType會return null

getRemoteUser: 回傳java.security.Principal物件

isUserInRole: 表示user內含於某個特定角色中

isSecure: request是否是以HTTPS傳送

PLT.11.1.7 Response Content Types
portlet可透過getResponseContentType取得default content type
getResponseContentTypes中要回傳container支援的所有content types

getResponseContentType可回傳 *

PLT.11.1.8 Internationalization
container要決定user產生reponse時使用的locale,container可以使用request中的 Accept-Language header訊息,PortletRequest.getLocale會回傳container選擇的locale

PLT.11.1.9 Portlet Mode
PortletRequest.getPortletMode容許portlet取得目前的 portlet mode
PortletRequest.isPortletModeAllowed 可決定是否支援某個portlet mode

PLT.11.1.10 Window State
PortletRequest.getWindowState 回傳目前的window state
PortletRequest.isWindowStateAllowed 可判斷是否可使用某個window state

PLT.11.2 ActionRquest Interface
ActionRequst extends PortletRequest,用在Portlet.processAction中

PLT.11.2.1 Retrieving Uploaded Data
input stream在client request中包含HTTP POST data(除了 application/x-www-form-urlencoded之外)時很有用
ActionRequest.getReader, getPortletInputStream 可取得POST data資料,可能會throw IllegalStateException

ActionRequest提供四個method處理input stream: getContentType, getCharacterEncoding, setCharacterEncoding, getContentLength,如果POST data是 application/x-www-form-urlencoded 這種type,則getReader/getPortletInputStream 會throw IllegalStateException

PLT.11.3 RenderRequest
目前RenderRequest沒有定義任何methods

PLT.11.4 Lifetime of the Request Objects
每一個request objects只在processAction or render method裡面可以使用


**********************
PLT.12 Portlet Response
PLT.12.1 PortletResponse Interface
PortletResponse定義ActionResponse, RenderResponse共用介面

PLT.12.1.1 Response Properties
PortletResponse.setProperty, addProperty

portlet要使用encodeURL建立URLs


PLT.12.2 ActionResponse Interface
ActionResponse extends PortletResponse,由Portlet.processAction使用,提供 redirect, set render parameters, change window state, change portlet mode 的功能

PLT.12.2.1 Redirections
sendRedirect必須要指定一個 fully qualified URL,否則會傳回 IllegalArgumentException

如果在ActionResponse.setPortletMode, setWindowState, setRenderParameter, setRenderParameters後面呼叫sendRedirect,就會 throw IllegalArgumentException

PLT.12.2.2 Portlet Modes and Window State Changes
setPortletMode可改變current portlet mode,如果指定一個不支援的mode,就會 throw PortletModeException

setWindowState可改變window state,如果指定一個不支援的state,就會throw WindowStateException

sendRedirect之後呼叫setPortletMode, setWindowState,就會 throw IllegalArgumentException

PLT.12.2.3 Render Parameters
ActionResponse.setRenderParameter, setRenderParameters設定render parameters

PLT.12.3 RenderResponse Interface
RenderResponse extends PortletResponse,用在Portlet.render

PLT.12.3.1 Content Type
RenderResponse.setContentType要跟PortletRequest.getResponseContentType吻合,否則會忽略設定值

getWriter, getPortletOutputStream呼叫前,就要先呼叫setContentType

PLT.12.3.2 Output Stream and Writer Objects
RenderResponse 將content寫入 OutputStream, or Writer

PLT.12.3.3 Buffering
RenderResponse.getBufferSize, setBufferSize, isCommitted, reset, resetBuffer, flushBuffer

getBufferSize: returns the size of the underlying buffer being used

setBufferSize:

isCommitted: 表示所有response bytes已經回傳給client

flushBuffer: 強制flush contents

reset: clear data in the buffer

PLT.12.3.4 Namespace encoding
getNamespace提供portlet保證回傳唯一字串的method(在整個portal page中唯一),必須在一次render request中,呼叫幾次都回傳一樣的字串

PLT.12.3.5 Portlet Title
由container決定是否要支援自訂title
setTitle在每次portlet commit output前一定要被呼叫一次

PLT.12.4 Lifetime of Response Objects
每一個response object只在processAction, render裡面才能使用


******************
PLT.13 Portal Context
PortalContext 提供整個portal的資料,portlet可以呼叫

getPortalInfo: return portal vendor/version資料

getProperty, getPropertyNames: return portal properties

getSupportedPortletModes: return supported porlet modes

getSupportedWindowStates: return supported window states

getPortalContext: 從request object中取得 PortalContext object


**************************
PLT.14 Portlet Preferences
PLT.14.1 PortletPreferences Interface
portlet 可以在processAction過程中,修改preferences attributes

methods: getNames, getValue, setValue, getValues, setValues, getMap, isReadOnly, reset, store

ex:
PortletPreferences prefs = req.getPreferences();
String[] symbols =prefs.getValues("preferredStockSymbols",new String[]{"ACME","FOO"});
String url = prefs.getValue("quotesFeedURL",null);
int refreshInterval =Integer.parseInt(prefs.getValue("refresh","10"));

如果是read-only,則當setValue, reset時,會throw ReadOnlyException

store: 儲存修改後的PortletPreferences,如果在render中呼叫store,則會throw IllegalStateException

PLT.14.2 Preference Attributes Scopes

PLT.14.3 Preference Attributes definition



PreferredStockSymbols
FOO
XYZ
true


quotesFeedURL
http://www.foomarket.com/quotes




PLT.14.3.1 Localizing Preference Attributes
portlet spec沒有定義localizaing preference attributes

PLT.14.4 Validating Preference values

...

com.foo.portlets.XYZValidator



一個implements PreferencesValidator的class,必須要有thread safe manner
store必須要呼叫validator,可能會throw ValidatorException


*********************
PLT.15 Sessions
PortletSession介面

PLT.15.1 Creating a Session
PLT.15.2 Session Scope
PortletSession必須要scoped at the portlet application context level

PLT.15.3 Binding Attributes into a Session
PortletSession定義了兩個scope: APPLICATION_SCOPE, PORTLET_SCOPE
APPLICATION_SCOPE: 所有portlet可以使用的資料,javax.portlet.p.?,ID是container提供的id,一定要有?字元,ATTRIBUTE_NAME是用來設定PORTLET_SCOPE物件
PORTLET_SCOPE: 在一個portlet window中可以使用的資料

ex:
PortletSession session = request.getSession(true);
URL url = new URL("http://www.foo.com");
session.setAttribute("home.url",url,PortletSession.APPLICATION_SCOPE);
session.setAttribute("bkg.color","RED",PortletSession.PORTLET_SCOPE);

要得知有沒有物件新增或移除自Session,就要implements HttpSessionBindingListener,PortletSesionUtil提供判斷是否為PORTLET_SCOPE的物件,decodeAttributeName可以移除container prefix


PLT.15.4 Relationship with the Web Application HttpSession
PortletSesion必須把所有attributes存在HttpSession中

PLT.15.4.1 HttpSession Method Mapping
PortletSession.getCreationTime, getId, getLastAccessedTime, getMaxInactiveInterval, invalidate, isNew, setMaxInactiveInterval跟HttpSession一樣
getAttribute, setAttribute, removeAttribute, getAttributeNames除了跟HttpSession的一樣外,還要有額外的功能: APPLICATION_SCOPE attribute names必須要一樣,PORTLET_SCOPE的attribute name要有特定的prefix,不提供SCOPE功能的變型method必須要把全部的attributes視為PORTLET_SCOPE

PLT.15.5 Reserved HttpSession Attribute Names
以"javax.portlet."開頭的attributes保留給portlet使用

PLT.15.6 Session Timeouts

PLT.15.7 Last Accessed Times

PLT.15.8 Important Session Semantics



**********************
PLT.16 Dispatching Requests to Servlets and JSPs
PortletRequestDispatcher

PLT.16.1 Obtaining a PortletRequestDispatcher
portlet只能在render裡面使用PortletRequestDispatcher
可透過PortletContext.getRequestDispatcher, getNamedDispatcher取得PortletRequestDispatcher

getRequestDispatcher要有path String當參數,path一定要以"/"開頭,並在PortletContext裡面

getNamedDispatcher以servlet String當參數

PLT.16.1.1 Query Strings in Request Dispatcher Paths
ex:
String path = "/raisons.jsp?orderno=5";
PortletRequestDispatcher rd = context.getRequestDispatcher(path);
rd.include(renderRequest, renderResponse);

PLT.16.2 Using a Request Dispatcher
PortletRequestDispatcher.include

PLT.16.3 The Include Method
在render中可能會被呼叫很多次
不應該使用RequestDispatcher.forward

PLT.16.3.1 Included Request Parameters
必須要設定這些request attributes
javax.servlet.include.request_uri
javax.servlet.include.context_path
javax.servlet.include.servlet_path
javax.servlet.include.path_info
javax.servlet.include.query_string

PLT.16.3.2 Included Request Attributes
Request Attribute Type
javax.portlet.config javax.portlet.PortletConfig
javax.portlet.request javax.portlet.RenderRequest
javax.portlet.response javax.portlet.RenderResponse

PLT.16.3.3 Request and Response objects for Included Servlets/JSPs
HttpServletRequest.getProtocol, getRemoteAddr, getRemoteHost, getRealPath, getRequestURL 必須return null
HttpServletRequest.getPathInfo, getPathTranslated, getQueryString, getRequestURI, getServletPath必須要return path and query string infos
HttpServletRequest.getScheme, getServerName,getServerPort, getAttribute, getAttributeNames, setAttribute,removeAttribute, getLocale, getLocales, isSecure, getAuthType,getContextPath, getRemoteUser, getUserPrincipal, getRequestedSessionId,isRequestedSessionIdValid 要跟PortletRequest一樣

HttpServletRequest的這些methods必須不能作用,並要return null,getCharacterEncoding, setCharacterEncoding, getContentType, getInputStream and getReader. The getContentLength method of the HttpServletRequest must return 0.

The following methods of the HttpServletRequest must be based on the properties
provided by the getProperties method of the PortletRequest interface: getHeader,getHeaders, getHeaderNames, getCookies, getDateHeader and getIntHeader

The following methods of the HttpServletRequest must provide the functionality
defined by the Servlet Specification 2.3: getRequestDispatcher, getMethod,isUserInRole, getSession, isRequestedSessionIdFromCookie, and isRequestedSessionIdFromUrl, isRequestedSessionIdFromURL


The getMethod method of the HttpServletRequest must always return "GET".

The following methods of the HttpServletResponse must return null: encodeRedirectURL
and encodeRedirectUrl. The following methods of the HttpServletResponse must be equivalent to the methods of the RenderResponse of similar name: getCharacterEncoding, setBufferSize, flushBuffer,resetBuffer, reset, getBufferSize, isCommitted, getOutputStream, getWriter, encodeURL
and encodeUrl.

The following methods of the HttpServletResponse must perform no operations: setContentType, setContentLength, setLocale, addCookie, sendError, sendRedirect, setDateHeader, addDateHeader, setHeader, addHeader, setIntHeader, addIntHeader and setStatus. The containsHeader method of the HttpServletResponse must return false.

The getLocale method of the HttpServletResponse must be based on the getLocale method of the RenderResponse.


PLT.16.3.4 Error Handling
除了IOException之外,所有Exception都要包裝PortletException

*************************
PLT.17 User Information
PLT.17.1 Defining User Attributes



User Given Name
user.name.given


User Last Name
user.name.family



User eMail
user.home-info.online.email


Company Organization
user.business-info.postal.organization




PLT.17.2 Accessing User Attributes
ex:
Map userInfo = (Map) request.getAttribute(PortletRequest.USER_INFO);
String givenName = (userInfo!=null)? (String) userInfo.get("user.name.given") : ""
String lastName = (userInfo!=null)? (String) userInfo.get("user.name.family") : "";

PLT.17.3 Important Node on User Information
目前沒有standard user information java api

********************
PLT.18 Caching
cache content可增加效能
PLT.18.1 Expiration Cache
ex: 300

If the expiration render invocation the cache property is set to -1, the cache does not expire.

**********************
PLT.19 Portlet Applications
PLT.19.1 Relationship with Web Applications


**********************
PLT.20 Security
PLT.20.1 Introduction
PLT.20.2 Roles
PLT.20.3 Programmatic Security
Request.getRemoteUser, isUserInRole, getUserPrincipal

getRemoteUser: return client用來認證的 user name
isUserInRole
getUserPrincipal: return java.security.Principal物件

security-role-ref

...

...

FOO
manager


...
...


PLT.20.4 Specifying Security Constaints

...

accountSummary
...

...

Secure Portlets

accountSummary


CONFIDENTIAL


...


PLT.20.5 Propagation of Security Identity in EJB

***********************
PLT.21 Packaging and Deploymenet Descriptor
/WEB-INF/portlet.xml
Portlet classes in the /WEB-INF/classes directory
Portlet Java ARchive files /WEB-INF/lib/*.jar

The following deployment descriptor values must be unique in the scope of the portlet application definition:
portlet
custom-portlet-mode
custom-window-state
user-attribute

The following deployment descriptor values must be unique in the scope of the portlet definition:
init-param
supports
preference
security-role-ref


***********************
PLT.22 Portlet Tag Library
讓JSP能include portlets,並直接使用RenderRequest, RenderResponse

container必須提供portlet tag library implementation

ex: <%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>

PLT.22.1 defineObejcts Tag
要定義以下這些變數
RenderRequest renderRequest
RenderResponse renderResponse
PortletConfig portletConfig

defineObjects不能有任何attributes與body content
ex:
<%=renderResponse.setTitle("my portlet title"); %>

PLT.22.2 actionURL Tag
actionURL產生指到目前的portlet的URL
non-required attributes:
windowState(String: non-required)
portletMode(String: non-required)
var(String: non-required): name of the exported scoped variable for the action URL
secure(String: non-required): true/ false

ex:




PLT.22.3 renderURL Tag
windowState
portletMode
var
secure
ex:





PLT.22.4 namespace Tag
ex: Foo


PLT.22.5 param Tag
name
value
ex:

*****************************
PLT.A Custom Portlet Modes
PLT.A.1 About
PLT.A.2 Config
PLT.A.3 Edit_defaults
PLT.A.4 Preview
PLT.A.5 Print

ex:

...

...

config

...

...

config

...


**************************
PLT.B Markup Fragments
Portlet產生的HTML fragments不能使用 base, body, iframe, frame, frameset, head, html, title這些tags
Portlet產生的XHTML, XHTML-Basic fragments不能使用 base, body, iframe, head, html, title這些tags


********************
PLT.C CSS Style Definitions