??xml version="1.0" encoding="utf-8" standalone="yes"?>
在Faces API中有两个cL要经怋用的. 一个是FacesContext 一个是ExternalContext.首先讲解如何使用FacesContext .
Ҏ?span class="hilite1">JSFhQFacesServlet对象都会为其获取一个javax.faces. context.
FacesContextcȝ实例。FacesServlet对象下?个取自Web容器的对象传ljavax.faces.context.FacesContextFactory对象的getFacesContextҎQ以此来做到q一点:
?nbsp; javax.servlet.ServletContext
?nbsp; javax.servlet.ServletRequest
?nbsp; javax.servlet.ServletResponse
q意味着FacesContext的实例里包含了所有处?span class="hilite1">JSFh所需的每个请求的状态信息。图3-1展示了FacesContext实例里封装的其他一些对象?
3.2.1 获取当前实例
一个经常用到的Ҏ是静态的getCurrentInstanceҎQ它q回当前的FacesContext实例。此Ҏ的签名如下:
public static FacesContext getCurrentInstance()
下面的代码是一个用此方法获取FacesContext当前实例的例子:
FacesContext facesContext = FacesContext.getCurrentInstance();
3.2.2 获取和修改组件树
FacesContext实例里最重要的内Ҏh面的组件树。组件树是由javax.faces.tree.TreecL表示?本章后面?#8220;使用Treec?#8221;一节会讨论)。FacesContext实例的tree属性就是Tree对象?
要获取或修改Tree对象Q可使用tree属性的dҎ和赋值方法:
public abstract Tree getTree()
public abstract void setTree(Tree tree)
3.2.3 d和获取消?
?
h处理生命周期里,可能会遇到错误。比如,当验证器执行输入验证Ӟ因ؓ用户输入了不正确的|验证可能p|Q当lg试图把输入D{换ؓl定到组件的?
型对象所需的类型时Q也可能会失败。所有消息都必须存放到FacesContext实例里以备后面进行处理。比如,您可能希望在面里显C错误消息,从?
为用h正错误提供帮助?
错误消息是由javax.faces.application.Message接口(W?1章再详细讨论)来表C的Q您可以通过使用FacesContextcȝaddMessageҎ向FacesContext实例里添加Message对象。这个方法的{如下Q?
public abstract void addMessage(UIComponent component, Message message)
如果component不ؓI,新加入的message关联到component上。否则,它就不与M特定lg的实例相兟?
举例来说Q验证器在验证组件值失败时可调用FacesContext的addMessageҎQ传入值无效的lg及一个包含特定错误消息的Message对象?
所有添加到FacesContext实例的Message对象都被加入C个集合里。可通过调用getMessagesҎ的两个重载方法之一来获取加入的Message对象Q?
public abstract Iterator getMessages()
public abstract Iterator getMessages(UIComponent component)
W一UŞ式的调用在一个Iterator里返回所有Message对象Q而第二种形式的调用则仅返回与l定UIComponent相关联的Message对象?
3.2.4 d和获取请求处理事?
UIComponent 可以生成FacesEvent对象。比如,当单M?span class="hilite3">UICommandlgӞ它会生成一个ActionEvent对象(ActionEventcL FacesEventcȝ子类)。这个FacesEvent对象需要在FacesContext实例里保存v来,以备h处理生命周期里的下一步处理事?时所用?
可通过使用FacesContextcȝaddFacesEventҎ向FacesContext实例dFacesEvent对象。此Ҏ的签名如下:
public abstract void addFacesEvent(FacesEvent event)
要提取先前添加的FacesEvent对象Q可调用getFacesEventsҎQ其{如下Q?
public abstract Iterator getFacesEvents()
此方法返回FacesEvent时的序与其在队列中的顺序一致?
3.2.5 向Response对象里写入信?
?了向Response对象里写入信息,FacesContextcL供了两个属性,一个是
javax.faces.Context.ResponseStreamcdQ另一个是
javax.faces.context.ResponseWritercd。ResponseStreamcd的对象用于输Zq制数据Q?
ResponseWritercd的对象则用于输出字符。这些属性的dҎ和赋值方法如下:
public abstract ResponseStream getResponseStream()
public abstract void setResponseStream(ResponseStream responseStream)
public abstract ResponseWriter getResponseWriter()
public abstract void setResponseWriter(ResponseWriter responseWriter)
3.2.6 获取和设|地?
W?1章将会讨论到Q?span class="hilite1">JSF支持国际化和本地化。这意味着您可以根据用L地区军_发送什么样的回应信息。locale属性里存放了当前处理中所用的Locale对象?
初始状况下,locale属性的值和|络览器里指定的地区是一LQ但可以修改q个|从而发送输出所使用的地区将独立于浏览器所使用的地区。此属性的dҎ和赋值方法如下:
public abstract Locale getLocale()
public abstract void setLocale(Locale locale)
3.2.7 操作h处理生命周期
FacesContextc还提供了两个方法与h处理生命周期q行交互Q?
?nbsp; 在当前阶D늚处理完成后,调用renderResponseҎ通知JSF实现把控制权转到呈现响应阶段。也是_处于当前阶段和呈现响应阶D之间的所有其他阶D都不再执行?
?nbsp; 调用responseCompleteҎQ告?span class="hilite1">JSF实现此次h的HTTP响应已经完成(比如在用了HTTP重定向的情况?。因此,当前阶段完成后,必须中止h处理生命周期的处理?
q些Ҏ的签名如下:
public abstract void renderResponse()
public abstract void responseComplete()
3.2.8 获取其他h状态信?
其他每个h的状态信息封装在ExternalContext对象里,可以使用getExternalContextҎ获取该对象:
public abstract ExternalContext getExternalContext()
现在讲解ExternalContext?
?
用ExternalContextcL供的Ҏ可以获取ServletContext、ServletRequest和ServletResponse?
象,构造FacesContext实例旉要这些对象。除此之外,ExternalContext实例提供了包装器ҎQ可以用这些方法获得原来需要从
ServletContext、ServletRequest及ServletResponse对象上调用一些方法获得的信息?
3.3.1 获取ServletContext、ServletRequest和ServletResponse对象
可用下列方法获取servlet信息Q?
?nbsp; getContext 此方法可获取Web应用中与当前h相关联的ServletContext对象。其{如下Q?
public abstract Object getContext()
?nbsp; getRequest 此方法可获取代表当前正在处理的请求的ServletRequest对象。其{如下Q?
public abstract Object getRequest()
?nbsp; getResponse 此方法可获取代表当前正在呈现的响应的ServletResponse对象。其{如下Q?
public abstract Object getResponse()
q些Ҏ都是q回一个java.lang.Object对象Q不是servletҎ的类型,q样可以JSF实现独立于其q行的环境。比如,JSF既可用于Web容器Q也可以用于其他容器Q如portlet{?
3.3.2 获取ServletContextҎ?
getApplicationMapҎq回一个包含ServletContext对象里全部特性名/值对的Map对象。下面是此方法的{Q?
public abstract java.util.Map getApplication()
作ؓ一个例子,下面的代码可获取一个名叫databaseUtility的特性:
Object contextAttribute = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Map contextMap = externalContext.getApplicationMap();
if (contextMap!=null)
contextAttribute = contextMap.get("databaseUtility");
3.3.3 获取Session对象及其Ҏ?
?qExternalContext对象可访问与当前h相关联的Session对象。getSessionҎ可取回当前用L
javax.servlet.http.HttpSession对象Q如果当前用h有相应的Session对象Q此Ҏ的行为由传入的参数决定:如果?
该方法传入了一个true|它会创徏一个Session对象Q否则,它会q回null。下面是getSessionҎ的签名:
public abstract Object getSession(boolean create)
此方法其实是javax.servlet.http.HttpServletRequest接口中getSessionҎ的包装器?
getSessionMapҎq回一个包含与当前h相关联的Session对象里所有特性名/值对的Map对象。下面是它的Ҏ{Q?
public abstract java.util.getSessionMap()
?
获取Session对象里的Ҏ,可调用MapcȝgetҎQ传入要获取的特性名卛_。文中没有指明在当前请求没有相应Session对象的情况下Q?
此方法是q回nullq是一个空的Map对象。所以在调用Map的getҎ之前Q需要先查Map是否为null。下面的代码是获取SessionҎ?
的例子:
Object sessionAttribute = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Map sessionMap = externalContext.getSessionMap();
if (sessionMap!=null)
sessionAttribute = sessionMap.get(key);
最后一行的key是一个包含特性名的字W串?
3.3.4 获取ServletContext对象的初始参?
getInitParameterҎ是ServletContext对象的getInitParameterҎ的包装器Q用q个Ҏ可以提取在部|描q符(web.xml文g)里用context-init元素指定的初始参数倹{此Ҏ的签名如下:
public abstract String getInitParameter(String parameterName)
举例来说Q如果在部v描述W声明了如下context-init元素Q?
<context-param>
<param-name>contactPerson</param-name>
<param-value>Scott Jobim</param-value>
</context-param>
下面代码中的字符串变量initParam的g是Scott Jobim?
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
String initParam = externalContext.getInitParameter("contactPerson");
getInitParameterMapҎq回一个包含ServletContext对象中全部初始参数的Map对象。其{如下Q?
public abstract java.util.Map getInitParameterMap()
Z获取一个初始参数的|使用Map对象的getҎQ同时传递初始参数的名称。比如,下面的代码把初始参数databaseName的D出到控制台?
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Map paramMap = externalContext.getInitParameterMap();
if (paramMap!=null) {
System.out.println(paramMap.get("databaseName"));
}
3.3.5 获取Request对象的特?
getRequestMapҎq回一个包含当前Request对象中全部特性名/值对的Map对象。其Ҏ{如下Q?
public abstract java.util.Map getRequestMap()
作ؓ一个例子,下面的代码可用来提取Request对象里的Ҏ:
Object requestAttribute = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Map requestMap = externalContext.getRequestMap();
if (requestMap!=null)
requestAttribute = requestMap.get(key);
最后一行里的Key是一个包含要提取的属性名的字W串?
3.3.6 讉KRequest对象里的参数名和?
getRequestParameterMap、getRequestParameterNames和getRequestParameterValuesMapҎ可用来访问Request对象里的参数名和倹{?
getRequestParameterMapq回一个包含Request对象里全部参数名/值对的Map对象。其{如下Q?
public abstract java.util.Map getRequestParameterMap()
作ؓ一个例子,下面的代码可用来提取名ؓid的请求参数的|
String id = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Map requestParameterMap = externalContext.getRequestParameterMap();
if (requestParameterMap!=null)
id = (String) requestParameterMap.get("id");
getRequestParameterNames
Ҏq回一个包含全部请求参数名的Iterator。此Ҏ其实是ServletRequest.getParameterNamesҎ的包装器。不?
的是QExternalContextcȝgetRequestParameterNamesq回一个IteratorQ而不?
java.util.Enumeration。此Ҏ的签名如下:
public abstract java.util.Iterator getRequestParameterNames()
作ؓ一个例子,下面的代码把所有的h参数?值对输出到控制台?
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Map requestParameterMap = externalContext.getRequestParameterMap();
Iterator parameterNames = externalContext.getRequestParameterNames();
while (parameterNames.hasNext()) {
String parameterName = (String) parameterNames.next();
String parameterValue =
(String) requestParameterMap.get(parameterName);
System.out.println(parameterName + " : " + parameterValue);
}
getRequestParameterValuesMap
Ҏq回一个包含Request对象里全部参数名/值对的Map对象。此Ҏ与getRequestParameterMapҎ很相|?
getRequestParameterValuesMap可返回全部相同参数名的倹{在此方法返回的Map对象上调用get(key)ҎQ这一点等?
于获取当前请求的ServletRequestq在其上调用getParameterValues(key)。也是_Map对象q回的是一个字W串?
l。GetRequestParameterValuesMapҎ的签名如下:
public abstract java.util.Map getRequestParameterValuesMap()
下面例子中的代码把请求参数id的全部D出到控制台?
String[] id = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Map requestParameterValuesMap = externalContext.getRequestParameterValuesMap();
if (requestParameterValuesMap!=null) {
id = (String[]) requestParameterValuesMap.get("id");
// print all values of id
for (int i=0; i<id.length; i++) {
System.out.println(id[i]);
}
}
3.3.7 获取h头的名和?
getRequestHeaderMapҎq回一个包含当前请求中全部头名/值对的Map对象。其Ҏ{如下Q?
public abstract java.util.Map getRequestHeaderMap()
举个例子来说Q下面的代码提取host头的|
String host = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Map headerMap = externalContext.getRequestHeaderMap();
if (headerMap!=null) {
host = (String) headerMap.get("host");
System.out.println(host);
}
注意Q?
报头的名U是不区分大写的。比如,对getRequestHeaderMapq回的Map对象分别用host、Host和Host作ؓ参数来调用getҎQ其l果是一L?
getRequestHeaderValuesMapҎ与getRequestHeaderMapҎ怼。但在getRequestHeader
ValuesMapҎq回的Map对象上调用getҎ会得C个字W串的数l。getRequestHeaderValuesMapҎ的签名如下:
public abstract java.util.Map getRequestHeaderValuesMap()
在getRequestHeaderValuesMapҎq回的Map对象上调用getҎ会返回一个java.util.Enumeration倹{?
下面的代码用getRequestHeaderValuesMapҎ来获取一个包含全部头?值对的Map对象Q然后在此Map对象上调用getҎ以获取全部Accept-Encoding头的|q将l果输出到控制台?
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Map headerValuesMap = externalContext.getRequestHeaderValuesMap();
if (headerValuesMap!=null) {
Enumeration headers =
(Enumeration) headerValuesMap.get("Accept-Encoding");
while (headers.hasMoreElements()) {
String value = (String) headers.nextElement();
System.out.println(value);
}
}
3.3.8 获取Cookie
getRequestCookiesҎ是HttpServletRequest.getCookiesҎ的包装器Q它q回一个javax.servlet.http.Cookie对象的数l,数组中是当前Request对象里的全部Cookie。此Ҏ的签名如下:
public abstract Cookie[] getRequestCookies()
例如Q下面的代码取得当前h中的全部Cookie对象Q然后在l果数组上@环,输出全部Cookie的名和倹{?
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Cookie[] cookies = externalContext.getRequestCookies();
for (int i=0; i<cookies.length; i++) {
Cookie cookie = cookies[i];
String cookieName = cookie.getName();
String cookieValue = cookie.getValue();
System.out.println(cookieName + " : " + cookieValue);
}
getRequestCookieMap
Ҏq回一个包含当前请求中全部Cookie的、以Cookie的名UC为键的Map对象。在此Map对象上调用getҎ会返回一?
javax.servlet.http.Cookie对象。GetRequestCookieMapҎ的签名如下:
public abstract java.util.Map getRequestCookieMap()
例如Q下面的代码取得名ؓpassword的Cookie对象q将其D出到控制台?
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Map cookieMap = externalContext.getRequestCookieMap();
if (cookieMap!=null) {
Cookie cookie = (Cookie) cookieMap.get("password");
if (cookie!=null)
System.out.println("Value:" + cookie.getValue());
}
注意Q?
Cookie名称区分大小写?
3.3.9 获取场所
getRequestLocaleҎ是ServletRequest.getLocaleҎ的包装器Q它q回Request对象中的Locale对象。此Ҏ的签名如下:
public abstract java.util.Locale getRequestLocale()
例如Q下面的代码取回用户的场所q输场所的显Ca和显C国家?
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Locale locale = externalContext.getRequestLocale();
System.out.println("Language:" + locale.getDisplayLanguage());
System.out.println("Country:" + locale.getDisplayCountry());
3.3.10 获取上下文\?
getRequestContextPath是HttpServletRequest.getContextPathҎ的包装器Q它q回hURI中指明请求上下文的上下文路径部分。其Ҏ{如下Q?
public abstract String getRequestContextPath()
下面的代码段把请求URI的上下文路径输出到控制台Q?
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
System.out.println("Context path:" +
externalContext.getRequestContextPath());
对于URL http://localhost:8080/JSFCh03/faces/test.jsp来说QgetRequestContextPathҎ的返回gؓ/JSFCh03?
getRequestPathInfo
Ҏ是HttpServletRequest.getPathInfoҎ的包装器Q它q回当客Lq行h时与客户端发送的URL相关联的额外路径?
息。这部分信息跟在servlet路径信息的后面,但在查询字符串之前。getRequestPathInfoҎ的签名如下:
public abstract String getRequestPathInfo()
例如Q下面代码输求URL的\径信息?
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
System.out.println("Path info:" +
externalContext.getRequestPathInfo());
对于URL http://localhost:8080/JSFCh03/faces/test.jsp而言QgetRequestPathInfoҎ的返回gؓtest.jsp?
3.3.11 获取资源路径
getResourcePaths
Ҏ是ServletContextcȝgetResourcePathsҎ的包装器Q它q回一个Set对象Q其中包含Web应用中最长子路径与传入的
路径参数相匹配的资源路径。表C子目录的\径以“/”l束。返回的路径是相对于Web应用根\径的相对路径Qƈ?#8220;/”开始。此Ҏ的签名如下:
public abstract java.util.Set getResourcePaths(String path)
比如Q考虑如下代码Q?
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
Set resourcePaths = externalContext.getResourcePaths("/");
Iterator iterator = resourcePaths.iterator();
while (iterator.hasNext()) {
String path = (String) iterator.next();
System.out.println(path);
}
System.out.println("----------------------------");
resourcePaths = externalContext.getResourcePaths("/WEB-INF");
iterator = resourcePaths.iterator();
while (iterator.hasNext()) {
String path = (String) iterator.next();
System.out.println(path);
}
q段代码两次调用了getResourcePathsҎQ第一ơ传?#8220;/”Q第二次传入“/WEB-INF”。如果在一个目录结构如?-2所C的Web应用里运行以上代码,则返回的W一个Set里包含如下\径:
/order.jsp
/index.jsp
/Styles.css
/images/
/details.jsp
/WEB-INF/
/checkOut.jsp
/browse.jsp
/shoppingCart.jsp
/search.jsp
/menu.jsp
W二个Set里包含如下\径:
/WEB-INF/faces-config.xml
/WEB-INF/web.xml
/WEB-INF/classes/
/WEB-INF/lib/
?-2 试getResourcesPath的目录结?
getResourceAsStreamҎ是ServletContext.getResourceAsStream的包装器Q它q回指定路径中作为java.io.InputStream对象的资源。其Ҏ{如下Q?
public abstract java.io.InputStream getResourceAsStream(String path)
3.3.12 ~码URL
encodeURLҎ是HttpServletResponse.encodeURLҎ的包装器Q它~码l定的URLQ其Ҏ是加入会话的ID信息Q或者,如果不需要这个步骤,则直接将l定的URL原封不动地返回。其Ҏ{如下Q?
public abstract String encodeURL(String url)
在portlet中?span class="hilite1">JSFӞencodeActionURL和encodeResourceURLҎ很有用。encodeActionURLqURL作ؓ参数传递,造成动作在入?portlet中v作用。这个方法的{如下Q?
public abstract String encodeResourceURL(String sb)
encodeResourceURLҎqURL作ؓ参数传递,引用资源以在入口/portlet中v作用。该Ҏ造成URL需要根据包括的特定入口q行重定向。实际上Q它单地q回一个绝对URL。下面是encodeResourceURLҎ的签名:
public abstract String encodeResourceURL(String sb)
3.3.13 分派h
dispatchMessageҎ可根据当前上下文分派h。对servlet而言Q它通过调用forward实现q一点;而对portlet而言Q则是通过调用includeҎ实现q一炏V此Ҏ的签名如下:
public abstract void dispatchMessage(String requestURL)
throws java.io.IOException, FacesException
<img id="indicator1" src="${pageContext.request.contextPath}/images/indicator.gif"
alt="Loading Info" style="display:none"/>