dyerac  
dyerac In Java
公告

日历
<2006年12月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456
统计
  • 随笔 - 36
  • 文章 - 10
  • 评论 - 94
  • 引用 - 0

导航

常用链接

留言簿(5)

随笔分类(49)

随笔档案(36)

文章分类(11)

文章档案(10)

相册

dyerac

搜索

  •  

积分与排名

  • 积分 - 78702
  • 排名 - 706

最新随笔

最新评论

阅读排行榜

评论排行榜

 
    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;
    }

}

posted on 2006-12-02 02:33 dyerac in java... 阅读(2946) 评论(4)  编辑  收藏
评论:
  • # re: 在JSF中用Filter模拟Get请求  逃兵 Posted @ 2006-12-02 13:05
    搞不懂,我经常在jsf中,经常以project.faces?name=dollyCal这种形式即用url来传输参数,后台用String name= (String) FacesContext.getCurrentInstance()
    .getExternalContext().getRequestParameterMap().get("name");来获取"name"的参数,
    也不需要先链接其他页面再导航过来。
    有必要写这么多余而又复杂的代码吗?  回复  更多评论   

  • # re: 在JSF中用Filter模拟Get请求  阿蛋 Posted @ 2008-02-22 17:24
    楼上兄弟你就不知道了...

    在你自己的 filter 中 FacesContext.getCurrentInstance() 返回的是 null...  回复  更多评论   

  • # # re: 在JSF中用Filter模拟Get请求  阿蛋 Posted @ 2008-02-22 17:25
    啊哈,搞错了!!!! 抱歉了..  回复  更多评论   

  • # re: 在JSF中用Filter模拟Get请求  hongingr Posted @ 2014-05-26 10:36
    我自己在web.xml中配了filter后就不能正常运行了。。。请问能否把前台必须的代码和配置文件也放出来呢?因为是初学者很困扰,感激不尽~~  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
 
Copyright © dyerac in java... Powered by: 博客园 模板提供:沪江博客