??? JSF作為如今JavaEE標準之一,基于組件的設計為Java的web開發帶來了極大的便利性。然而在設計上,JSF拋棄了傳統的GET請求方式,所有JSF的表單都已post方式提交。這樣雖然在安全性等方面有一定好處,但是也帶來了一些不便,比如,由JSF開發的web應用難以為每個單元定位。
?? 上述單元定位的意思是,比如你開發了一個project.faces用于動態顯示project的內容。由于是post提交表單,那么一個叫dollyCal的項目和一個叫nirvana的項目將同樣顯示為project.faces,這樣每次用戶都需要通過導航瀏覽自己需要的項目,而不能通過對固定網頁的收藏來一次性瀏覽。
??? 解決上述問題可以通過filter來模擬get請求。
???以下還是以dollyCal舉例:
?? GET請求下url形式為project.faces?name=dollyCal
??? 則通過filter攔截該請求,取出dollyCal字段,然后調用FacesContext,初始化相應的managed-bean,從數據庫中讀出dollyCal的相關信息填充到managed-bean中,再通過dispatcher導航到相應頁面即可。這樣用戶可以project.faces?name=dollyCal形式輕松訪問一個項目,方便其收藏和訂閱
???

if?(request?instanceof?HttpServletRequest)?
{
????????????HttpServletRequest?r?=?(HttpServletRequest)?request;
????????????String?s?=?r.getQueryString();

????????????if?(s?!=?null?&&?s.startsWith("project=")?&&?s.length()?>?8)?
{
????????????????String?name?=?s.substring(8);

????????????????if?(!PersistenceUtil.validateProject(name))?
{
????????????????????FacesContext?fcg?=?getFacesContext(request,response);
????????????????????ProjectViewBean?pjv=(ProjectViewBean)fcg.getApplication().getVariableResolver().resolveVariable(fcg,"pjv");

????????????????????try?
{
????????????????????????ProjectBean?p=PersistenceUtil.getProjectByName(name);
????????????????????????pjv.setProject(p);

????????????????????}?catch?(Exception?e)?
{
????????????????????????//?TODO?Auto-generated?catch?block
????????????????????????e.printStackTrace();
????????????????????}
????????????????????RequestDispatcher?rd=request.getRequestDispatcher("/projectView.faces");
????????????????????rd.forward(request,?response);
????????????????}
????????????}??? 唯一需要注意的問題是,filter實際上處于JSF的管理區域之外,因此不能調用FacesContext.getCurrentInstance方法來獲得JSF上下文,而需要通過request, response來創建當前JSF上下文。再從該上下文中查出managed-bean,進行數據填充,
? 以下是完整代碼,說明如下:
?? ProjectViewBean是projectView.faces頁面的managed-bean, 首先解析url中要查詢的項目名稱,從數據庫中讀出相應信息,再從上下文中查詢出該bean,填充信息即可。這樣再訪問該頁面時就會得到想要的結果。
package?org.myibm;

import?java.io.IOException;

import?javax.faces.FactoryFinder;
import?javax.faces.context.FacesContext;
import?javax.faces.context.FacesContextFactory;
import?javax.faces.lifecycle.Lifecycle;
import?javax.faces.lifecycle.LifecycleFactory;
import?javax.servlet.Filter;
import?javax.servlet.FilterChain;
import?javax.servlet.FilterConfig;
import?javax.servlet.RequestDispatcher;
import?javax.servlet.ServletContext;
import?javax.servlet.ServletException;
import?javax.servlet.ServletRequest;
import?javax.servlet.ServletResponse;
import?javax.servlet.http.HttpServletRequest;

import?org.myibm.beans.ProjectViewBean;
import?org.myibm.persistence.bean.ProjectBean;
import?org.myibm.utils.PersistenceUtil;


public?class?ParserFilter?implements?Filter?
{

????private?FilterConfig?filterConfig?=?null;


????public?void?destroy()?
{
????????//?TODO?Auto-generated?method?stub
????????filterConfig?=?null;
????}

????public?void?doFilter(ServletRequest?request,?ServletResponse?response,

????????????FilterChain?chain)?throws?IOException,?ServletException?
{
????????//?TODO?Auto-generated?method?stub

????????if?(request?instanceof?HttpServletRequest)?
{
????????????HttpServletRequest?r?=?(HttpServletRequest)?request;
????????????String?s?=?r.getQueryString();

????????????if?(s?!=?null?&&?s.startsWith("project=")?&&?s.length()?>?8)?
{
????????????????String?name?=?s.substring(8);

????????????????if?(!PersistenceUtil.validateProject(name))?
{
????????????????????FacesContext?fcg?=?getFacesContext(request,response);
????????????????????ProjectViewBean?pjv=(ProjectViewBean)fcg.getApplication().getVariableResolver().resolveVariable(fcg,"pjv");

????????????????????try?
{
????????????????????????ProjectBean?p=PersistenceUtil.getProjectByName(name);
????????????????????????pjv.setProject(p);

????????????????????}?catch?(Exception?e)?
{
????????????????????????//?TODO?Auto-generated?catch?block
????????????????????????e.printStackTrace();
????????????????????}
????????????????????RequestDispatcher?rd=request.getRequestDispatcher("/projectView.faces");
????????????????????rd.forward(request,?response);
????????????????}
????????????}
????????}

????????try?
{
????????????//?System.out.print("filter?begins!");
????????????chain.doFilter(request,?response);
????????????//?System.out.print("filter?works!");

????????}?finally?
{

????????}
????}


????public?void?init(FilterConfig?arg0)?throws?ServletException?
{
????????//?TODO?Auto-generated?method?stub
????????this.filterConfig?=?arg0;
????}


????private?abstract?static?class?InnerFacesContext?extends?FacesContext?
{
????????protected?static?void?setFacesContextAsCurrentInstance(

????????????????FacesContext?facesContext)?
{
????????????FacesContext.setCurrentInstance(facesContext);
????????}
????}

????private?FacesContext?getFacesContext(ServletRequest?request,

????????????ServletResponse?response)?
{
????????//?Try?to?get?it?first
????????FacesContext?facesContext?=?FacesContext.getCurrentInstance();
????????if?(facesContext?!=?null)
????????????return?facesContext;

????????FacesContextFactory?contextFactory?=?(FacesContextFactory)?FactoryFinder
????????????????.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
????????LifecycleFactory?lifecycleFactory?=?(LifecycleFactory)?FactoryFinder
????????????????.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
????????Lifecycle?lifecycle?=?lifecycleFactory
????????????????.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);

????????//?Either?set?a?private?member?servletContext?=
????????//?filterConfig.getServletContext();
????????//?in?you?filter?init()?method?or?set?it?here?like?this:
????????//?ServletContext?servletContext?=
????????//?((HttpServletRequest)request).getSession().getServletContext();
????????//?Note?that?the?above?line?would?fail?if?you?are?using?any?other
????????//?protocol?than?http
????????ServletContext?servletContext?=?((HttpServletRequest)?request)
????????????????.getSession().getServletContext();

????????//?Doesn't?set?this?instance?as?the?current?instance?of
????????//?FacesContext.getCurrentInstance
????????facesContext?=?contextFactory.getFacesContext(servletContext,?request,
????????????????response,?lifecycle);

????????//?Set?using?our?inner?class
????????InnerFacesContext.setFacesContextAsCurrentInstance(facesContext);

????????//?set?a?new?viewRoot,?otherwise?context.getViewRoot?returns?null
????????//?UIViewRoot?view?=
????????//?facesContext.getApplication().getViewHandler().createView(facesContext,
????????//?"yourOwnID");
????????//?facesContext.setViewRoot(view);

????????return?facesContext;
????}
}
