JSF 2 Partial Requests не использует FacesContext с фабрики
Кажется, что частичные запросы не используют экземпляры лица лица, которые созданы FacesContextFactory
Реализации.
Вот код в UIViewRoot#processDecodes
это указывает на то же самое
if (context.getPartialViewContext().isPartialRequest() &&
!context.getPartialViewContext().isExecuteAll()) {
context.getPartialViewContext().processPartial(PhaseId.APPLY_REQUEST_VALUES);
} else {
super.processDecodes(context);
}
Кажется, что PartialViewContext хранит реализацию FacesContextImpl по умолчанию и использует ее для вызова методов жизненного цикла. (Обратите внимание, что метод processPartial не принимает объект контекста, потому что он использует собственный объект, хранящийся внутри)
Это ошибка или этот код по определенной причине?
Спасибо
2 ответа
FacesContext
экземпляры уникальны для каждого потока, а FacesServlet
создает ThreadLocal<FacesContext>
в начале запроса при получении FacesContext
(который является договором FacesContextFactory#getFacesContext)
и удаляет его в конце ответа, связанного с запросом сервлета HTTP (вызывая FacesContext#release
).
Всякий раз, когда вы делаете FacesContext#getCurrentInstance()
в вашем коде JSF вы всегда будете получать один и тот же экземпляр во время всей обработки запросов / ответов сервлетов HTTP.
О методе UIViewRoot#processDecodes
Я действительно не вижу ни одной строки, которая, вероятно, могла бы указывать, что метод использует собственный созданный экземпляр, а не переданный. Какая линия заставила вас так думать?
Это можно увидеть в FacesServlet#service
метод, который создает FacesContext
от FacesContextFactory
Вот выдержка из 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
,
Поскольку вы говорите - вы установили некоторые дополнительные параметры для FacesContext
которые возвращаются из FacesContextFactory
это означает, что у вас есть своя собственная реализация FacesContextFactory
, если это так, то вы уверены, что ваш экземпляр вводится в FacesServlet
а не моджарры com.sun.faces.context.FacesContextFactoryImpl
(если вы используете мохарру)?
Вот как я заставил это работать. Ниже приведен код в моей фабрике контекста пользовательских лиц
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);
}