User Tools

Site Tools


jsf-ru:faq:request_lifecycle

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
jsf-ru:faq:request_lifecycle [2006/01/14 19:58] – добавлено описание фазы Process Validations slonopotamusjsf-ru:faq:request_lifecycle [2006/01/22 17:01] slonopotamus
Line 1: Line 1:
 [[jsf-ru:faq|Назад к FAQ]] [[jsf-ru:faq|Назад к FAQ]]
 ====== JSF Request Lifecycle ====== ====== JSF Request Lifecycle ======
 +
  
 ===== В теории ===== ===== В теории =====
Line 49: Line 50:
  
 Если какой-либо из вызванных методов ''decode()'' или слушатель событий (//event listener//), который обрабатывал событие, вызвал метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#responseComplete()|FacesContext#responseComplete()]], то обработка текущего запроса должна быть немедленно прекращена. Если какой-либо из вызванных методов ''decode()'' или слушатель событий (//event listener//), который обрабатывал событие, вызвал метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#renderResponse()|FacesContext#renderResponse()]], то управление должно немедленно перейти к фазе [[#render.response|Render Response]]. Иначе управление должно перейти к фазе [[#process.validations|Process Validations]]. Если какой-либо из вызванных методов ''decode()'' или слушатель событий (//event listener//), который обрабатывал событие, вызвал метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#responseComplete()|FacesContext#responseComplete()]], то обработка текущего запроса должна быть немедленно прекращена. Если какой-либо из вызванных методов ''decode()'' или слушатель событий (//event listener//), который обрабатывал событие, вызвал метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#renderResponse()|FacesContext#renderResponse()]], то управление должно немедленно перейти к фазе [[#render.response|Render Response]]. Иначе управление должно перейти к фазе [[#process.validations|Process Validations]].
 +
 +
  
  
 ==== Process Validations ==== ==== Process Validations ====
-В процессе создания вида (''view'') для текущего запроса, к компонентам могут быть добавлены [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/validator/Validator.html|валидаторы]]. Помимо этого, компоненты могут сами реализовывать логику валидации в их методах ''validate()''((Найти явадок.))((Внимание! В следующей версии JSF этот метод будет помечен как ''deprecated'', поэтому исбегайте его использования.)).+В процессе создания вида (''view'') для текущего запроса, к компонентам могут быть добавлены [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/validator/Validator.html|валидаторы]]. Помимо этого, компоненты могут сами реализовывать логику валидации в их методах ''validate()''((Найти явадок.)).
  
 На стадии [[#process.validations|Process Validations]] жизненного цикла запроса реализация JSF должна вызвать метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/UIViewRoot.html#processValidators(javax.faces.context.FacesContext)|UIViewRoot#processValidators()]]. По-нормальному это повлечёт за собой рекурсивный вызов метода [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/UIComponent.html#processValidators(javax.faces.context.FacesContext)|UIComponent#processValidators()]] для каждого компонента в дереве компонентов, как написано в документации к этому методу. Обратите внимание, что компоненты, реализующие [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/EditableValueHolder.html|EditableValueHolder]], у которых свойство ''immediate'' выставлено в ''true'', уже выполнили свою валидацию на стадии [[#apply.request.values|Apply Request Values]]. На стадии [[#process.validations|Process Validations]] жизненного цикла запроса реализация JSF должна вызвать метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/UIViewRoot.html#processValidators(javax.faces.context.FacesContext)|UIViewRoot#processValidators()]]. По-нормальному это повлечёт за собой рекурсивный вызов метода [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/UIComponent.html#processValidators(javax.faces.context.FacesContext)|UIComponent#processValidators()]] для каждого компонента в дереве компонентов, как написано в документации к этому методу. Обратите внимание, что компоненты, реализующие [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/EditableValueHolder.html|EditableValueHolder]], у которых свойство ''immediate'' выставлено в ''true'', уже выполнили свою валидацию на стадии [[#apply.request.values|Apply Request Values]].
Line 61: Line 64:
  
 Если какой-либо из вызванных методов ''validate()'' или слушатель событий (//event listener//), который обрабатывал событие, вызвал метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#responseComplete()|FacesContext#responseComplete()]], то обработка текущего запроса должна быть немедленно прекращена. Если какой-либо из вызванных методов ''validate()'' или слушатель событий (//event listener//), который обрабатывал событие, вызвал метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#renderResponse()|FacesContext#renderResponse()]], то управление должно немедленно перейти к фазе [[#render.response|Render Response]]. Иначе управление должно перейти к фазе [[#update.model.values|Update Model Values]]. Если какой-либо из вызванных методов ''validate()'' или слушатель событий (//event listener//), который обрабатывал событие, вызвал метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#responseComplete()|FacesContext#responseComplete()]], то обработка текущего запроса должна быть немедленно прекращена. Если какой-либо из вызванных методов ''validate()'' или слушатель событий (//event listener//), который обрабатывал событие, вызвал метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#renderResponse()|FacesContext#renderResponse()]], то управление должно немедленно перейти к фазе [[#render.response|Render Response]]. Иначе управление должно перейти к фазе [[#update.model.values|Update Model Values]].
 +
  
 ==== Update Model Values ==== ==== Update Model Values ====
-FIXME+Если обрабока запроса дошла до этой стадии, то предполагается, что запрос синтаксически и семантически((Не спрашивайте меня, что это означает.)) корректен, что локальное значение каждого компонента в дереве компонентов было обновлено, и что теперь можно обновлять данные в модели приложения для подготовки к выполнению событий приложения, которые находятся в очереди. 
 + 
 +В течение фазы [[#update.model.values|Update Model Values]], реализация JSF должна вызвать метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/UIViewRoot.html#processUpdates(javax.faces.context.FacesContext)|UIViewRoot#processUpdates()]]. По-нормальному это повлечёт за собой вызов метода [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/UIComponent.html#processUpdates(javax.faces.context.FacesContext)|UIComponent#processUpdates()]] для каждого компонента в дереве, как описано в документации к этому методу. Обновление модели выполняется в методе ''updateModel()''((Найти явадок.)) компонента. 
 + 
 +В процессе обновления модели, события могут добавляться в очередь компонентами, у которых вызывается метод ''updateModel()''. После этого они (события) будут распространены заинтересованным слушателям событий. В конце этой фазы у всех подходящих((В оригинале ''appropriate''.)) объектов данных будут обновлены их значения до значений, содержащихся в соответствующих компонентах, а локальные значения в компонентах будут очищены. 
 + 
 +Если какой-либо из вызванных методов ''updateModel()'' или слушатель событий (//event listener//), который обрабатывал событие, вызвал метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#responseComplete()|FacesContext#responseComplete()]], то обработка текущего запроса должна быть немедленно прекращена. Если какой-либо из вызванных методов ''updateModel()'' или слушатель событий (//event listener//), который обрабатывал событие, вызвал метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/context/FacesContext.html#renderResponse()|FacesContext#renderResponse()]], то управление должно немедленно перейти к фазе [[#render.response|Render Response]]. Иначе управление должно перейти к фазе [[#invoke.application|Invoke Application]]. 
 + 
 ==== Invoke Application ==== ==== Invoke Application ====
-FIXME+Если обрабока запроса дошла до этой стадии, то предполагается, что все обновления модели выполнены и оставшиеся события должны быть переданы приложению. Реализация JSF должна убедиться, что вызван метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/UIViewRoot.html#processApplication(javax.faces.context.FacesContext)|UIViewRoot#processApplication()]]. По умолчанию этот метод распространяет все события, у которых задан идентификатор фазы [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/event/PhaseId.html#INVOKE_APPLICATION|PhaseId.INVOKE_APPLICATION]]. 
 + 
 +Продвинутые приложения (или фрэймворки) могут заменять ''ActionListener'', вызвав метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/application/Application.html#setActionListener(javax.faces.event.ActionListener)|Application#setActionListener()]] для текущего приложения. Однако реализация JSF должна предоставить ''ActionListener'' по умолчанию, который ведёт себя согласно [[ActionListener|описанию]]. 
 + 
 + 
 ==== Render Response ==== ==== Render Response ====
-FIXME+Эта фаза производит два действия: 
 +  - Выводит результат клиенту 
 +  - Сохраняет состояние результата для последующий запросов. 
 + 
 +Эти две задачи объединены в одну фазу потому, что в JSP-приложениях вывод результата может вызвать построение вида (''view'') по мере того, как выводится страница. Поэтому невозможно сохранить состояние до тех пор пока вид не построен, а состояние необходимо сохранить дотого, как вывод будет отправлен клиенту для того, чтобы сохранить у клиента состояние. 
 + 
 +JSF поддерживает различные подходы, которые реализации JSF могут использовать при создании результата, который соответствует содержимому результирующего вида, включая: 
 +  * Получение всего вывода напрямую из результатов вызова методов ''encode()'' (либо компонентов либо соответствующих рендереров). 
 +  * Чередование результатов энкодинга компонентов с содержимым которое динамически генерируется логикой приложения. 
 +  * Чередование результатов энкодинга компонентов с контентом, который копируется из статического "шаблонного" ресурса. 
 +  * Использование результатов энкодинга компонентов посредством вызовов методов в динамическом ресурсе (именно так отображаются компоненты в виде custom-тэгов в JSP-страницах). 
 + 
 +Из-за большого количества возможных вариантов, механизм реализации фазы [[#render.response|Render Response]] не может быть точно описан. Однако, все реализации этой фазы должны удовлетворять следующим требованиям: 
 +  * Реализация JSF должна предоставить реализацию ''ViewHandler'''а по умолчанию, которая вызывает метод [[http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/RequestDispatcher.html#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse)|RequestDispatcher#forward()]] для ресурса, путь (относительно контекста) которого равен идентификатору вида текущего дерева компонентов. 
 +  * Если весь вывод получается из энкодирующих методов компонентов или ассоциированных с ними рендереров, то дерево компонентов должно обходиться в таком же порядке, в каком оно обходилось на более ранних фазах. 
 +  * Если содержимое вывода получается из энкодирующих методов и дополнительных источников, компоненты могут рендериться (мда) в произвольном порядке((Обычно порядок задаётся специальной разметкой (например, JSP-тэгами) в шаблоне, ассоциированном с деревом компонентов.)). 
 +  * В процессе рендеринга дополнительные компоненты могут быть добавлены в дерево компонентов на основании информации, имеющейся у реализации [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/application/ViewHandler.html|ViewHandler]]'а((Например, эта техника используется когда custom-тэги в JSP страницах используются в качестве технологии для рендеринга, как описано в [[jsp_integration|Интеграции с JSP]])). Однако, перед добавлением новых компонентов, реализация ''ViewHandler'''а должна предварительно проверить, не содержится ли уже указанный компонент в дереве компонентов. Если уже содержится (возможно из-за того, что предыдущие фазы создали его заранее), должны использоваться свойства и атрибуты уже существующего компонента((Вот этот момент я плохо понял.)). 
 +  * Ни при каких условиях не должен выбираться компонент для рендеринга, если у какого-либо из его родительских компонентов свойство ''rendersChildren'' установлено в ''true''. В таких случаях тот родительский компонент должен сам рендерить своих детей, когда он будет выбран. 
 +  * Если метод [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/UIComponent.html#isRendered()|isRendered()]] у компонента возвращает ''false'', то рендерер для этого компонента не должен производить никакой разметки и никакой из детей или facet'ов этого компонента не должен быть отрендерен. 
 + 
 +Для компонентов, которые реализуют интерфейс [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/ValueHolder.html|ValueHolder]] (например, ''UIInput'' и ''UIOutput''), должно выполняться преобразование данных в соответствии с тем, как это описано в [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/UIOutput.html|документации]] к ''UIOutput''
 + 
 +По завершении рендеринга, конечное состояние вида должно быть сохранено посредством методов класса [[http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/application/StateManager.html|StateManager]]. Эта информация о состоянии должна быть доступна при последующем запросе, чтобы ей можно было воспользоваться в фазе [[#restore.view|Restore View]]. Более подробная информацию о ''StateManager'''е можно найти [[StateManager|здесь]]. 
 ===== На практике ===== ===== На практике =====
 Делаем простенький [[.:PhaseListener]]: Делаем простенький [[.:PhaseListener]]:
Line 115: Line 155:
  
 Вывод: если вы хотите, чтобы какой-то кусок кода вызывался при каждом обращении к JSF-приложению (например, вы хотите [[.:with_jaas|защитить]] какие-то страницы от просмотра, то необходимо либо писать фильтр, чтобы запросы к JSF-сервлету проходили сначала через него, либо писать [[.:PhaseListener]], который будет висеть на фазе ''RESTORE_VIEW''. Вывод: если вы хотите, чтобы какой-то кусок кода вызывался при каждом обращении к JSF-приложению (например, вы хотите [[.:with_jaas|защитить]] какие-то страницы от просмотра, то необходимо либо писать фильтр, чтобы запросы к JSF-сервлету проходили сначала через него, либо писать [[.:PhaseListener]], который будет висеть на фазе ''RESTORE_VIEW''.
 +
 +
 +===== Ссылки по теме =====
 +  * [[http://www-128.ibm.com/developerworks/java/library/j-jsf2|JSF for nonbelievers: The JSF application lifecycle]] (англ.)
 +
jsf-ru/faq/request_lifecycle.txt · Last modified: 2019/06/12 16:08 by 127.0.0.1