JSF 2 部分请求不使用工厂中的 FacesContext

发布于 2024-11-01 15:39:41 字数 560 浏览 0 评论 0原文

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

这是 UIViewRoot#processDecodes 中的代码,它表明了相同的情况。

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

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

这是一个错误还是出于特定原因而存在此代码?

谢谢

It seems like the partial requests don't use the faces context instances that are created by FacesContextFactory implementations.

Here's the code in UIViewRoot#processDecodes that indicates the same

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

It seems like the PartialViewContext stores the default FacesContextImpl implementation within it and uses it to call lifecycle methods. (Notice that the processPartial method doesn't take a context object, because it uses it own internally stored one)

Is this a bug or this code in there for a specific reason?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄荷港 2024-11-08 15:39:41

FacesContext 实例对于每个线程都是唯一的,FacesServlet 在请求开始时创建一个 ThreadLocal,同时获取 FacesContext (这是 FacesContextFactory#getFacesContext 的协定) 并在与 HTTP servlet 请求关联的响应末尾删除它(通过调用 FacesContext#release )。

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

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

FacesServlet#service方法中可以看到,它从FacesContextFactory创建了FacesContext,这里摘录自< code>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 不能拥有 FacesContext 实例,而该实例不是来自 FacesContextFactory

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

FacesContext instances are unique per thread, and The FacesServlet creates a ThreadLocal<FacesContext> on the beginning of the request while acquiring the FacesContext (which is the contract of FacesContextFactory#getFacesContext) and removes it on the end of the response associated with the HTTP servlet request (by calling the FacesContext#release).

Whenever you do a FacesContext#getCurrentInstance() in your JSF code, you'll always get the same instance throughout the entire HTTP servlet request/response processing.

About the method UIViewRoot#processDecodes,I really don't see any line which probably can indicate that method uses it's own created instance rather than the passed one. Which line made you think that?

It can be seen in the FacesServlet#service method that it creates the FacesContext from The FacesContextFactory, here is a excerpt from the FacesServlet#service method which shows this -

// 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();
}

Considering this, I don't feel UIViewRoot#processDecodes can have the FacesContext instance which is not from FacesContextFactory.

Since you're saying - you have set some additional parameters to the FacesContext which get returned from FacesContextFactory, that means you have your own custom implementation of FacesContextFactory, if this is the case then are you sure that your instance is injected in the FacesServlet and not mojarra's com.sun.faces.context.FacesContextFactoryImpl (if you're using mojarra)?

誰認得朕 2024-11-08 15:39:41

这是我让它发挥作用的方法。下面是我的自定义面孔上下文工厂中的代码

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

Here's how i got it to work. Below is the code in my custom faces context factory

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文