O JSF (Java Server Faces) é um poderoso framework para desenvolvimento de aplicações Web em Java, veio com o intuito de substituir a “velha” interface em JSP por uma mais moderna e de fácil utilização, assim o desenvolvedor não precisa se preocupar com códigos HTML, layout, entre outros aspectos que fogem do real objetivo da aplicação.
Para se utilizar o JSF é necessário o entendimento do seu ciclo de vida, assim o desenvolvedor poderá ter noção do que acontece de forma transparente porém muito importante.
O JSF possui 6 ciclos, são eles:
- Restore View
- Apply Request View
- Process Validations
- Update Model Values
- Invoke Application
- Render Response
Explicaremos cada fase através de exemplos práticos do JSF, mas antes precisaremos configurar o Listener que será responsável por monitorar essa mudança de estados doJSF, para isso implementaremos uma interface chamada PhaseListener. Veja na listagem 1 como ficará nossa interface.
Listagem 1: Implementando a Interface PhaseListener
package br.com.debugjsf.listener;import javax.faces.event.PhaseEvent;import javax.faces.event.PhaseId;ner; public class LifeCycleListener imimport javax.faces.event.PhaseList eplements PhaseListener { public PhaseId getPhaseId() {forePhase(PhaseEvent event) {return PhaseId.ANY_PHASE; } public void b e System.out.println("INICIANDO FASE: " + event.getPhaseId()); }("FINALIZANDO FASE: " + event.getPhaseId());public void afterPhase(PhaseEvent event) { System.out.printl n }}
Vamos a explicação do código acima: Criamos uma classe que implementa o PhaseListener, nesta temos os seguintes métodos:
- getPhaseId(): Apenas retorna um PhaseId que pode ser um daqueles 6 que citamos logo no inicio (1 - Restore View, 2 - Apply Request View, 3 - Process Validations, 4 - Update Model Values, 5 - Invoke Application e 6 - Render Response).
- beforePhase(): Antes de uma determinada fase iniciar este método é chamado.
- afterPhase(): Depois de uma determinada fase terminar este método é chamado.
Após termos nosso PhaseListener implementado, vamos configurar o nosso arquivo faces-config.xml para dizer a nossa aplicação quem será o nosso Listener, ou seja, apontar qual será a classe responsável por escutar as mudanças de fase do JSF. Veja na listagem 2 como ficou a configuração do nosso faces-config.xml.
Listagem 2: Configurando faces-config.xml
<lifecycle><phase-listener>br.com.debugjsf.listener.LifeCycleListener</phase-listener></lifecycle>
Temos enfim nossa aplicação configurada para escutar todas as fases do JSF, partiremos agora para os exemplos em cada fase. A saída de ciclo completo do JSF no console deve ser algo parecido com a listagem 3.
Listagem 3: Saída no console de um ciclo completo JSF
INICIANDO FASE: RESTORE_VIEW 1FINALIZANDO FASE: RESTORE_VIEW 1INICIANDO FASE: APPLY_REQUEST_VALUES 2FINALIZANDO FASE: APPLY_REQUEST_VALUES 2INICIANDO FASE: PROCESS_VALIDATIONS 33 INICIANDO FASE: UPDATE_MODEL_VALUES 4FINALIZANDO FASE: PROCESS_VALIDATIONS FINALIZANDO FASE: UPDATE_MODEL_VALUES 4LIZANDO FASE: INVOKE_APPLICATION 5 IINICIANDO FASE: INVOKE_APPLICATION 5 FIN ANICIANDO FASE: RENDER_RESPONSE 66FINALIZANDO FASE: RENDER_RESPONS E
Configurando a aplicação de exemplo no JSF
Vamos primeiramente configurar nossa página XHTML, que usaremos para realizar a depuração.
Listagem 4: teste.xhtml
<h:form><h:inputTextbinding="#{myBean.inputComponent}"value="#{myBean.inputValue}".inputChanged}"> <f:converter converterId="myvalueChangeListener="#{myBea nConverter" /> <f:validator validatorId="myValidator" /> </h:inputText><h:outputText<h:commandButton value="submit" action="#{myBean.action}" /> binding="#{myBean.outputComponent}" value="#{myBean.outputValue}" /> <h:messages /></h:form>
Vamos as explicações:
- input text: Este componente está realizando um binding com a propriedade inputComponent do nosso ManagedBean, seu valor é armazenado na propriedade inputValue do ManagedBean, temos ainda um listener associado a ele (inputChanged) que escuta toda vez que alguma alteração é realizada no valor deste campo. Para finalizar este componente, temos ainda um conversor e um validador associados ao mesmo.
- commandButton: O nosso commandButton dispensa explicações, ele apenas aciona um action em nosso ManagedBean.
- outputText: Por fim, este componente que é apenas um “label” possui um binding também em nosso ManagedBean e um atributo associado ao seu valor.
Vamos agora ver como será nosso ManagedBean.
Listagem 5: MyBean.java
package br.com.debugjsf.mb;import javax.faces.component.html.HtmlInputText;import javax.faces.component.html.HtmlOutputText;import javax.faces.event.ValueChangeEvent;ra Binding privatpublic class MyBean { //Componentes p ae HtmlInputText inputComponent;tComponent; //Armazena valores dos comprivate HtmlOutputText outp uponentes private String inputValue; private String outputValue;action() { opublic MyBean() { log("constructed"); } public voi dutputValue = inputValue; log("succes"); }og(inputComponent); return inputComponpublic HtmlInputText getInputComponent() { lent; } public String getInputValue() { log(inputValue); return inputValue;output} public HtmlOutputText getOutputComponent() { log(outputComponent); return Component; } public String getOutputValue() { log(outputValue);inputComponent) {return outputValue; } public void setInputComponent(HtmlInputTex tlog(inputComponent); this.inputComponent = inputComponent; }this.inputValue = inputValue; }public void setInputValue(String inputValue) { log(inputValue) ; public void setOutputComponent(HtmlOutputText outputComponent) { log(outputComponent);s do inputText e escreve no console quando houvethis.outputComponent = outputComponent; } //Escuta por alteraçõ er public void inputChanged(ValueChangeEvent event) { log(event.getOldValue() + " to " + event.getNewValue()); }dName = Thread.currentThread().getStackTrace()[2].getMethodName();//Escreve um LOG no console, para acompanharmos o ciclo de vida private void log(Object object) { String meth o System.out.println("MyBean " + methodName + ": " + object); }}
E no nosso faces-config.xml configuraremos o ManagedBean assim como na listagem abaixo.
Listagem 6: Configurando faces-config.xml para o ManagedBean
<converter><converter-id>myConverter</converter-id><converter-class>br.com.debugjsf.util.MyConverter</converter-class></converter> <validator> <validator-id>myValidator</validator-id>> </validator> <managed-bean> <managed-bean-name>myBean</managed-be<validator-class>br.com.debugjsf.util.MyValidator</validator-clas san-name> <managed-bean-class>br.com.debugjsf.mb.MyBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope></managed-bean>
Vamos recapitular o que temos até agora:
- Configuramos o nosso PhaseListener para escutar as alterações de fase do JSF
- Criamos uma aplicação exemplo para testar nosso PhaseListener, onde essa aplicação é composta por: 1 view (teste.xhtml), 1 ManagedBean (MyBean.java), 1 Converter e 1 Validator. Então vamos agorar criar nosso Converter e nosso Validator.
Listagem 7: Criando o Converter da nossa aplicação
package br.com.debugjsf.util;import javax.faces.component.UIComponent;import javax.faces.context.FacesContext;blic class MyConverter implements Convimport javax.faces.convert.Converter; p uerter {c Object getAsObject(FacesContext context, UIComponent component, String value) {publ iSystem.out.println("MyConverter getAsObject: " + value); return value; }{ System.out.println("MyConverter getAsString: " + value); return (Strinpublic String getAsString(FacesContext context, UIComponent component, Object value )g) value; }}
Listagem 8: Criando o Validator da nossa aplicação
package br.com.debugjsf.util;import javax.faces.component.UIComponent;import javax.faces.context.FacesContext;mport javax.faces.validator.ValidatorExcimport javax.faces.validator.Validator; ieption; public class MyValidator implements Validator {component, Object value) throws ValidatorException { System.opublic void validate(FacesContext context, UIComponent ut.println("MyValidator validate: " + value); } }
Enfim temos nossa aplicação totalmente criada e configurada para escutar as fases do JSF, é óbvio que você pode adaptar o PhaseListener para sua aplicação, colocamos esta apenas para exemplificar o uso deste.
Conclusão
Enfim, o objetivo deste artigo não é explicar com detalhes o ciclo de vida do JSF, e sim configurar um depurador para acompanhar na prática o ciclo de vida deste framework, pois melhor que a teoria, é a prática. Tendo o conhecimento básico de cada ciclo de vida e acompanhando este depurador, você conseguirá ter uma visão melhor de como funciona tal mecanismo e verá a teoria se aplicando na prática.
Isso porque muitos desenvolvedores sentem dificuldade de “ver” como funciona o ciclo de vida do JSF, pois este é totalmente transparente ao desenvolvedor.
Autor: Ronaldo Lanhellas
0 comentários :
Postar um comentário
Observação: somente um membro deste blog pode postar um comentário.