【问题标题】:Accessing a JSF managedBean from a Servlet [duplicate]从 Servlet 访问 JSF managedBean [重复]
【发布时间】:2011-04-04 11:09:40
【问题描述】:

我需要知道从 servlet 访问 JSF managedBean(定义为具有应用程序范围)的最佳方法是什么。 目前我的 servlet 中有这样的东西:

  MyApplicationScopeBean bean = null;
  try {
   FacesContext fContext = FacesUtil.getFacesContext(req, resp);
   ServletContext sc = (ServletContext) fContext.getExternalContext().getContext();
   bean = (MyApplicationScopeBean) sc.getAttribute("myManagedBean");   
  } catch (Exception e) {
   e.printStackTrace();
  }

FacesUtil.java(如http://balusc.blogspot.com/2006/06/communication-in-jsf.html 中所述):

import javax.faces.FactoryFinder;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FacesUtil {
    // Getters -----------------------------------------------------------------------------------
    public static FacesContext getFacesContext(
        HttpServletRequest request, HttpServletResponse response)
    {
        // Get current FacesContext.
        FacesContext facesContext = FacesContext.getCurrentInstance();
        // Check current FacesContext.
        if (facesContext == null) {
            // Create new Lifecycle.
            LifecycleFactory lifecycleFactory = (LifecycleFactory)
                FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); 
            Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
            // Create new FacesContext.
            FacesContextFactory contextFactory  = (FacesContextFactory)
                FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
            facesContext = contextFactory.getFacesContext(
                request.getSession().getServletContext(), request, response, lifecycle);
            // Create new View.
            UIViewRoot view = facesContext.getApplication().getViewHandler().createView(
                facesContext, "");
            facesContext.setViewRoot(view);                
            // Set current FacesContext.
            FacesContextWrapper.setCurrentInstance(facesContext);
        }
        return facesContext;
    }
    // Helpers -----------------------------------------------------------------------------------
    // Wrap the protected FacesContext.setCurrentInstance() in a inner class.
    private static abstract class FacesContextWrapper extends FacesContext {
        protected static void setCurrentInstance(FacesContext facesContext) {
            FacesContext.setCurrentInstance(facesContext);
        }
    }     
}

尝试从 servlet 访问 bean 时,我总是得到一个空值。
您有什么建议? 我在 Tomcat 6 上运行 JSF 1.2

感谢您的帮助。

【问题讨论】:

    标签: jsf servlets javabeans


    【解决方案1】:

    JSF 将应用程序范围的托管 bean 存储在 ServletContext 中。在 servlet 中,ServletContext 仅可通过继承的 getServletContext() 方法获得。您无需在其周围手动创建整个 FacesContext。为此目的,这只是一项不必要的昂贵任务。

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Bean bean = (Bean) getServletContext().getAttribute("bean");
        // ...
    }
    

    如果它返回null,那么它仅仅意味着JSF 还没有开始为你自动创建bean(即servlet 调用得太早)。然后,您需要自己创建和存储它。如果托管 bean 名称(属性键)相同,则 JSF 将使用它。

        if (bean == null) {
            bean = new Bean();
            getServletContext().setAttribute("bean", bean);
        }
    

    也就是说,这个 servlet 的目的是什么?你不是试图以错误的方式实现某些功能需求吗?

    【讨论】:

    • 好的,现在我知道问题出在哪里了。我有一个 managedBean,它有一个方法可以创建我需要的 bean,但是当我到达 servlet 时,它不在 ServletContext 中,因为它从未真正加载过。 servlet 的目的是使用 OutputStream 编写文件,以便我的用户能够保存 Web 服务调用的结果(PDF 文件)。我知道这不是最好的方法,但我在这里面临最后期限任何帮助表示赞赏
    • 您也可以在托管 bean 方法中执行此操作。您可以在this answer 中找到一些提示。您当然不应该为此使用 servletcontext。它已在所有使用该网络应用程序的用户之间共享
    • 谢谢,通过您提供的示例,我已经修改了我的应用程序,现在它使用相同的 bean(会话范围)进行上传和下载,根本不需要弄乱 ServletContext。跨度>
    • >"BalusC:也就是说,这个 servlet 的目的是什么?您不是试图以错误的方式实现某些功能需求吗?"那是个很好的观点。我使用一个普通的servlet来做图像服务,然后根据BalusC的评论,我意识到bean也可以做到这一点,并且更容易与页面集成。
    • @Milo:图像服务又是一个故事。从这里开始:stackoverflow.com/q/11649524
    猜你喜欢
    • 2012-12-22
    • 1970-01-01
    • 2017-10-10
    • 2012-08-27
    • 2014-12-06
    • 2011-08-25
    • 2012-03-04
    • 2013-04-21
    • 2014-09-25
    相关资源
    最近更新 更多