O documento discute boas práticas para o uso do JavaServer Faces (JSF), incluindo: otimizar requisições AJAX e atualizações parciais de páginas; depurar o ciclo de vida de uma requisição JSF; usar Facelets para melhor desempenho; integrar JSF com bibliotecas como RichFaces e ExtJS.
Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)
JSF lifecycle and best practices optimization
1. JavaServer Faces (JSF)
e boas práticas
Rafael Ponte
rponte@gmail.com
http://www.rponte.com.br
2. | O que é importante
saber...
● Ciclo de vida de uma requisição JSF
● Otimizar requisições AJAX e atualizações
parciais de páginas
● Tudo funcionando em uma única página
● E Facelets, vai me servir para algo?
● Integrando JSF e ExtJs, em busca de
uma abordagem flexível
4. JSF Request lifecycle
Retrieve component tree
Restore from client or session May skip to
View render phase
Decode components or abort request
Apply Request (populate w/ String
Values values) Convert Strings to
Process Objects
Validations Validate Objects
Request
Update Call setters
Model on managed beans
Invoke bean
Invoke
method(s)
Response Application
Compute navigation
Call bean getters to Render
populate Response
components
5. | Depurando o ciclo
● A primeira chamada
● Refresh
● Submetendo o form
● Adiciona immediate=”true” para UIInput somente
● Adiciona immediate=”true” para UICommand somente
● Adiciona immediate=”true” para UIInput e UICommand
● Erro de conversão
● Erro de validação
6. | Depurando o ciclo
● A primeira chamada
* A fase é “pulada” pois não
houve form submit
1. Restore view
Como a UIViewRoot está vazia, não há o que fazer aqui
2. Apply request values *
3. Process validations *
4. Update model values *
5. Invoke application *
6. Render response
Os componentes são criados pela primeira vez e
armazenados na UIViewRoot e são setados os component
bindings.
7. | Depurando o ciclo
● Refresh
* A fase é “pulada” pois não
houve form submit
1. Restore view
Os componentes são restaurados do UIViewRoot e são
setados os component bindings
2. Apply request values *
3. Process validations *
4. Update model values *
5. Invoke application *
6. Render response
Os valores à serem exibidos são recuperados através dos
getters no managed bean, se eles não foram setados então o
valor default será null
8. | Depurando o ciclo
● Submetendo o form
1. Restore view
Os componentes são restaurados do UIViewRoot e são
setados os component bindings
2. Apply request values
Nada demais aqui. Os valores são recuperados do form e
setados nos componentes no UIViewRoot
3. Process validations
Os valores são recuperados como objetos dos componentes
através do método getAsObject() do converter e validados
pelo validator. Finalmente o valueChangeListener é invocado
[...]
9. | Depurando o ciclo
● Submetendo o form
4. Update model values
Os valores convertidos e validados serão agora setados
através do setters dos value bindings do managed bean
5. Invoke application
O processamento real da submissão do form acontece aqui
6. Render response
Os valores à serem exibidos são recuperados através dos
getters no managed bean, se um converter é definido então
o valor será obtido através do método getAsString() do
converter e o valor será exibido no form
10. | Depurando o ciclo
● Adiciona immediate=”true” para UIInput
1. Restore view
Os componentes são restaurados do UIViewRoot e são
setados os component bindings
2. Apply request values
Os valores são recuperados através do método getAsObject() do
converter, validados pelo validator e o valueChangeListener é
invocado. Daí os valores convertidos e validados são setados nos
componentes relevantes no UIViewRoot. Isso acontece aqui invés da
fase Process validations devido ao immediate=”true” no h:inputText
3. Process validations
Nada aqui. A conversão e validação já foram processadas na
fase anterior antes de os valores serem setados nos
componentes
[...]
11. | Depurando o ciclo
● Adiciona immediate=”true” para UIInput
4. Update model values
Os valores convertidos e validados serão agora setados
através do setters dos value bindings do managed bean
5. Invoke application
O processamento real da submissão do form acontece aqui
6. Render response
Os valores à serem exibidos são recuperados através dos
getters no managed bean, se um converter é definido então
o valor será obtido através do método getAsString() do
converter e o valor será exibido no form
12. | Depurando o ciclo
● Adiciona immediate=”true” para UICommand
1. Restore view
Os componentes são restaurados do UIViewRoot e são
setados os component bindings
2. Apply request values
O processamento real da submissão do form acontece aqui. Isso
acontece nesta fase invés da fase Invoke application devido ao
immediate=”true” no h:commandButton. Os componentes UIInput
que não possuem immediate=”true” setado serão ignorados, e
portanto, eles não serão convertidos nem validados
3. Process validations
Esta fase é “pulada” devido ao immediate=”true” no
h:commandButton
[...]
13. | Depurando o ciclo
● Adiciona immediate=”true” para UICommand
4. Update model values
Esta fase é “pulada” devido ao immediate=”true” no
h:commandButton
5. Invoke application
Esta fase é “pulada” devido ao immediate=”true” no
h:commandButton
6. Render response
Os valores à serem exibidos são recuperados através dos getters no
managed bean. Atenção: Como a fase Update model values é
“pulada” os value bindings não são setados e o getters dos value
bindings retornarão null. Os componentes UIInput que não possuem
immediate=”true” setado serão ignorados e não será possível
recuperar os valores do componente ou value binding.
14. | Depurando o ciclo
● Adiciona immediate=”true” para UIInput e
UICommand
1. Restore view
Os componentes são restaurados do UIViewRoot e são setados os component
bindings
2. Apply request values
Os valores são recuperados através do método getAsObject() do converter,
validados pelo validator e o valueChangeListener é invocado e os valores
convertidos e validados são setados no componentes relevantes no
UIViewRoot. Isso acontece aqui invés da fase Process validations devido ao
immediate=”true” no h:inputText. Finalmente o processamento real da
submissão do form acontece aqui. Isso acontece nesta fase ao invés da fase
Invoke application devido ao immediate=”true” no h:commandButton.
3. Process validations
Esta fase é “pulada” devido ao immediate=”true” no
h:commandButton [...]
15. | Depurando o ciclo
● Adiciona immediate=”true” para UIInput e
UICommand
4. Update model values
Esta fase é “pulada” devido ao immediate=”true” no h:commandButton
5. Invoke application
Esta fase é “pulada” devido ao immediate=”true” no h:commandButton
6. Render response
Os valores à serem exibidos são recuperados através dos getters no managed
bean. Atenção: Como a fase Update model values é “pulada” os value
bindings não são setados e o getters dos value bindings retornarão null. Mas
os valores ainda estão avaliados por component bindings que foram setados
na fase Apply request values, assim você poderá recuperar o valor do input
com inputBinding.getValue() no método action(). O novo valor do input será
também avaliado pelo ValueChangeEvent no método inputChanged()
16. | Depurando o ciclo
● Erro de conversão
1. Restore view
Os componentes são restaurados do UIViewRoot e são
setados os component bindings
2. Apply request values
Nada demais aqui. Os valores são recuperados do form e
setados nos componentes no UIViewRoot
3. Process validations
Os valores são recuperados como objetos dos componentes
através do método getAsObject() do converter onde um
ConverterException é lançado. O validator e o
valueChangeListener são “pulados”. O ciclo de vida “pulará”
imediatamente para a fase Render response
[...]
17. | Depurando o ciclo
● Erro de conversão
4. Update model values
Esta fase é pulada devido ao ConverterException
5. Invoke application
Esta fase é pulada devido ao ConverterException
6. Render response
Os valores à serem exibidos são recuperados através dos
getters no managed bean, explicitando os valores para qual
os ConverterException tem ocorrido
18. | Depurando o ciclo
● Erro de validação
1. Restore view
Os componentes são restaurados do UIViewRoot e são
setados os component bindings
2. Apply request values
Nada demais aqui. Os valores são recuperados do form e
setados nos componentes no UIViewRoot
3. Process validations
Os valores são recuperados como objetos dos componentes
através do método getAsObject() do converter e validados
pelo validator, onde um ValidatorException é lançado. O
valueChangeListener é “pulado”. O ciclo de vida “pulará”
imediatamente para a fase Render response
[...]
19. | Depurando o ciclo
● Erro de validação
4. Update model values
Esta fase é pulada devido ao ValidatorException
5. Invoke application
Esta fase é pulada devido ao ValidatorException
6. Render response
Os valores à serem exibidos são recuperados através dos
getters no managed bean, explicitando os valores para qual
os ValidatorException tem ocorrido
21. | Richfaces?
● Projeto da JBoss
● Insere funcionalidades AJAX em
aplicações JSF existentes
● Já inclui Ajax4jsf, é claro!
● Excelente compatibilidade com diversos
conjuntos de componentes
● Possui diversos componentes ricos
25. | Ajax4jsf?
Antes de enviar uma
requisição AJAX..
Decida o
que enviar!
26. | Ajax4jsf?
● Limitando regiões com a4j:region
● Diminuindo o trafégo na rede com
eventsQueue e requestDelay
● ajaxSingle=”true”, o lobo solitário
● Ninguém gosta de esperar, mas com
a4j:status as coisas até melhoram
27. | Ajax4jsf?
Antes de enviar uma
requisição AJAX..
Também decida
o que mudar!
28. | Ajax4jsf?
● Otimizando o atributo reRender
● Limitando-se a região,
renderRegionOnly=”true” e
selfRendered=”true”
● Limitando a lista de id's também ajuda,
limitToList=”true”
● Definindo áreas atualizavéis,
a4j:outputPanel
30. | Única página?
● Menos configurações para regras de
navegação
● Menos arquivos (jsp, xhtml) para
manutenção
● Renderização mais rápida
● Menos overhead no servidor
● Sem reload de página, lógico!
32. | Facelets?
● Desenvolvido especialmente para JSF
● Rápido templating de componentes e
páginas
● De 30% à 50% mais rápido que JSP
● Não está preso a Web Container
● JBoss Seam usa e abusa
33. | Facelets?
● Compatível com JSF 1.1 e JSF 1.2
● Excelente depuração de erros
● Será integrado ao JSF 2.0
● Utiliza-se de XHTML nas páginas (alguns
seres não gostam disso o.O)
● Compatível com a maioria (se não
todos) os conjuntos de componentes