【问题标题】:JSF 2 Partial Requests doesn't use FacesContext from the FactoryJSF 2 Partial Requests 不使用工厂的 FacesContext
【发布时间】:2011-08-06 11:37:18
【问题描述】:

似乎部分请求不使用由FacesContextFactory 实现创建的面孔上下文实例。

UIViewRoot#processDecodes 中的代码表示相同

if (context.getPartialViewContext().isPartialRequest() &&
    !context.getPartialViewContext().isExecuteAll()) {
    context.getPartialViewContext().processPartial(PhaseId.APPLY_REQUEST_VALUES);
} else {
    super.processDecodes(context);
}

似乎 PartialViewContext 在其中存储了默认的 FacesContextImpl 实现,并使用它来调用生命周期方法。 (请注意,processPartial 方法不采用上下文对象,因为它使用自己内部存储的对象)

这是一个错误还是其中的代码是出于特定原因?

谢谢

【问题讨论】:

  • 它会以某种方式损害您的逻辑还是您只是好奇?
  • 我需要使用我从工厂实例化的 FacesContext 来检索在其实例变量上设置的一些附加信息。从技术上讲,如果我愿意,我仍然可以从请求映射中检索原始值,但这会很奇怪

标签: ajax jsf jsf-2 mojarra facescontext


【解决方案1】:

这是我如何让它工作的。以下是我的自定义面孔上下文工厂中的代码

public FacesContext getFacesContext(Object context, Object request, Object response, Lifecycle lifecycle) throws FacesException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;

    ExternalContextFactory externalContextFactory = (ExternalContextFactory) getFactory(FactoryFinder.EXTERNAL_CONTEXT_FACTORY);
    ExternalContext externalContext = externalContextFactory.getExternalContext(context, request, response);

    // CustomFacesContext extends from FacesContextImpl
    CustomFacesContext facesContext = new CustomFacesContext(externalContext, lifecycle);

    ExceptionHandlerFactory exceptionHandlerFactory = (ExceptionHandlerFactory) getFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY);
    ExceptionHandler exceptionHandler = exceptionHandlerFactory.getExceptionHandler();
    facesContext.setExceptionHandler(exceptionHandler);
}

【讨论】:

    【解决方案2】:

    FacesContext 实例在每个线程中都是唯一的,FacesServlet 在请求开始时创建一个ThreadLocal<FacesContext>,同时获取FacesContext(这是FacesContextFactory#getFacesContext) 的合约并在结束时将其删除)与 HTTP servlet 请求关联的响应(通过调用 FacesContext#release)。

    每当您在 JSF 代码中执行 FacesContext#getCurrentInstance() 时,您将始终在整个 HTTP servlet 请求/响应处理过程中获得相同的实例。

    关于方法UIViewRoot#processDecodes,我真的没有看到任何可能表明该方法使用它自己创建的实例而不是传递的实例的行。哪条线让你这么想?

    可以在FacesServlet#service 方法中看到它从FacesContextFactory 创建FacesContext,这里是FacesServlet#service 方法的摘录,它显示了这一点 -

    // Acquire the FacesContext instance for this request
    FacesContext context = facesContextFactory.getFacesContext
       (servletConfig.getServletContext(), request, response, lifecycle);
    
    // Execute the request processing lifecycle for this request
    try {
     ...
    } catch (FacesException e) {
     ...
    }
    finally {
     // Release the FacesContext instance for this request
     context.release();
    }
    

    考虑到这一点,我觉得UIViewRoot#processDecodes 不能拥有不是来自FacesContextFactoryFacesContext 实例。

    既然你说 - 你已经为从FacesContextFactory 返回的FacesContext 设置了一些额外的参数,这意味着你有自己的FacesContextFactory 的自定义实现,如果是这种情况,那么你确定您的实例被注入FacesServlet 而不是 mojarra 的com.sun.faces.context.FacesContextFactoryImpl(如果您使用的是 mojarra)?

    【讨论】:

    • 更多地查看代码,我意识到我的 FacesContextFactory 的自定义实现会执行 delegate.getFacesContext() 这反过来调用默认工厂并通过 ExceptionHandlerFactoryImpl#getExceptionHandler. 初始化 PartialViewContext 我认为解决方案,我需要先致电ctx.setExceptionHandler(exceptionHandlerFactory.getExceptionHandler());,然后再致电代表。让我检查一下然后回来
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 2018-02-15
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 2011-09-01
    相关资源
    最近更新 更多