开发者

JSF 2 Partial Requests doesn't use FacesContext from the Factory

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().processPa开发者_如何学Pythonrtial(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


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)?


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜