Buscar

Desenvolvimento de Software para WEB

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 3, do total de 52 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 6, do total de 52 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 9, do total de 52 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Prévia do material em texto

Desenvolvimento de Software 
para WEB 
 
JSF (JavaServer Faces) – Parte 3 
Prof. Regis Pires Magalhães 
regispires@lia.ufc.br 
Agradecimentos 
• Agradecemos ao Prof. Fábio Dias (UFC Quixadá) 
por ter gentilmente cedido seus slides para 
adaptação e uso nesta disciplina. 
Melhor visualização dos erros 
• Project Stage 
• Existem no JSF configurações que podem 
auxiliar durante o desenvolvimento ou até 
mesmo em produção. 
▫ Chamadas de “estágios”. 
▫ “Development”, “UnitTest”, “SystemTest”, 
“Production” (default). 
▫ Modo development 
 Mostra erros e outros detalhes da aplicação de forma 
mais detalhada no próprio browser. 
Melhor visualização dos erros 
• Configurar o estágio atual da aplicação no web.xml: 
 <context-param> 
 <param-name>javax.faces.PROJECT_STAGE</param-name> 
 <param-value>Development</param-value> 
</context-param> 
Cuidado com a NullPointerException 
• Erro comum: 
▫ Esquecer de instanciar o objeto logo no atributo 
ou no construtor do Managed Bean. 
▫ Quando o formulário for submetido, o JSF 
recupera a referência para aquele objeto, através 
do getter, porém, ele estaria nulo. 
 
Cuidado com a NullPointerException 
@ManagedBean 
public class AutomovelBean { 
 private Automovel automovel = new Automovel(); 
 // getter e setter 
 public void salva() { 
 System.out.println("Marca: " + automovel.getMarca()); 
 } 
} 
Árvore de componentes 
• JSF lê arquivo .xhtml e monta uma árvore de 
componentes em memória. 
<h:form> 
<h:panelGrid columns="2"> 
Marca: <h:inputText 
 value="#{marcaBean.marca.nome}" 
required="true"/> 
</h:panelGrid> 
<br/> 
Árvore de componentes 
• Depois passa essa árvore para um renderizador 
para escrever o HTML a cada nó que passar. 
• JSF guarda na memória qual foi a árvore usada 
para gerar determinada tela. 
• Compara cada atributo da requisição com os 
campos que estavam disponíveis para o usuário. 
• Com as opções na mão, JSF valida se os dados 
enviados são compatíveis com os disponíveis. 
• Framework stateful  conhece todo o estado da 
tela e guarda isso através das requisições. 
Cliclo de vida das requisições no JSF 
6 Fases 
Fase 1 – Criar ou restaurar a árvore 
de componentes da tela 
• Restore View. 
• Lê o xhtml e cria a árvore de componentes em 
memória. 
• JSF faz um cache de árvores, guardando no 
cliente ou no servidor, o estado das telas 
acessadas por último. 
 <context-param> 
<param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
<param-value>client</param-value> 
<!-- valor padrão: server --> 
</context-param> 
Fase 2 – Aplicar valores da requisição na 
árvore de componentes 
• Apply Request Values 
• Buscar os valores informados pelo usuário e 
colocá-los nos seus respectivos componentes. 
• Seta os valores que o usuário digitou, sem se 
preocupar se ele é válido ou não. 
HtmlInputText nome = ... 
// JSF já conhece o componente 
 nome.setSubmittedValue("Fulano"); 
HtmlInputText idade = ... 
 idade.setSubmittedValue("28"); 
Fase 3 – Converter e Validar 
• Validate. 
• Fase mais perceptível. 
• 2 partes: converter e validar. 
• JSF tem conversores prontos para tipos basicos 
como Integer, Long, java.util.Date, entre outros. 
• Para converter tipos específicos é preciso criar e 
usar um conversor personalizado. 
• Depois de convertido, o valor informado será 
validado por um validador: 
▫ RequiredValidator, LongRangeValidator, etc. 
 
 
Fase 4 – Atualizar o modelo 
• Update Model. 
• Colocar esses valores válidos dentro do nosso 
modelo. 
• No final, temos nosso modelo com os valores 
corretos. 
HtmlInputText inputNome = ... // já convertido e validado 
HtmlInputText inputIdade = ... // já convertido e validado 
Pessoa pessoa = jsfAvaliaExpressionLanguage("#{pessoa}"); 
pessoa.setNome(inputNome.getValue()); 
pessoa.setIdade(inputIdade.getValue()); 
Fase 5 – Invocar ação da aplicação 
• Invoke Application. 
• Nessa fase ocorre a lógica da aplicação. 
• Exemplo: 
▫ Um sistema de universidade, em que para efetuar 
uma matrícula precisamos verificar: 
 Primeiro se não existe mensalidade em aberto; 
 Ou se já não existe um acordo sendo cumprido em 
relação às possíveis mensalidades em aberto. 
Fase 5 – Invocar ação da aplicação 
• Exemplo: 
public void efetuaMatricula(PropostaMatricula proposta){ 
 try{ 
 
servicoFinanceiro.validaSituacaoAluno(proposta.getAluno()); 
 // efetuaMatricula 
 } 
 catch(MensalidadesEmAbertoException e){ 
 // exibe mensagem para o usuário e aborta o a matrícula 
 } 
} 
Fase 6 – Renderizar a resposta 
• Render Response. 
• Última fase do ciclo de vida do JSF. 
• Chegamos nela se nas fases anteriores tudo 
ocorreu bem ou depois de um erro em fase 
intermediária. 
• Se ocorrer erro de conversão ou validação (fase 
3), as fases 4 e 5 são puladas e vamos direto para 
a fase 6 para mostrar novamente o formulário 
para que ele possa corrigi-lo, já com as devidas 
mensagens de erro. 
▫ Fase 1  Fase 2  Fase 3  Fase 6 
Fase 6 – Renderizar a resposta 
• Outra possibilidade: 
▫ Quando o usuário pede a página pela primeira vez, 
o JSF monta a árvore e já manda para a fase 6. 
▫ Na primeira requisição à aplicação, não haverá 
formulário sendo submetido, nem ação para ser 
invocada. 
 Fase 1  Fase 6 
Cliclo de vida das requisições no JSF 
6 Fases 
PhaseListener 
• Utilizamos um PhaseListener praticamente nas mesmas 
situações em que usaríamos um javax.servlet.Filter. 
• Mas em vez de envolver a requisição inteira, seremos 
notificados antes e depois de cada fase, o que faz com que 
tenhamos um acesso mais granular. 
• O método getPhaseId() devolve qual fase do JSF nosso 
listener irá escutar. Ou podemos devolver 
• PhaseId.ANY_PHASE para indicar que queremos ser 
notificados antes e depois de todas as fases. 
• Temos um método que e chamado antes do processamento 
da fase, beforePhase, e outro que e chamado depois, 
afterPhase. 
 
PhaseListener 
public class AutenticacaoPhaseListener implements PhaseListener { 
 private static final String RESTRICTION_PATTERN = "^/restrito/.*"; 
 
 public PhaseId getPhaseId() { 
 return PhaseId.RESTORE_VIEW; 
 } 
 
 public void beforePhase(PhaseEvent event) { } 
 
 public void afterPhase(PhaseEvent event) { 
 FacesContext context = event.getFacesContext(); 
 String viewId = context.getViewRoot().getViewId(); 
 boolean urlProtegida = Pattern.matches(RESTRICTION_PATTERN, viewId); 
 Object usuario = context.getExternalContext().getSessionMap(). 
 get("usuarioLogado"); 
 if(urlProtegida && usuario == null){ 
 NavigationHandler navigator = context.getApplication() 
 .getNavigationHandler(); 
 navigator.handleNavigation(context, null, "login"); 
 } 
 } 
} 
PhaseListener no faces-config.xml 
<navigation-rule> 
 <navigation-case> 
 <from-outcome>login</from-outcome> 
 <to-view-id>/login.xhtml</to-view-id> 
 </navigation-case> 
</navigation-rule> 
<lifecycle> 
 <phase-listener> 
 facesmotors.AutenticacaoPhaseListener 
 </phase-listener> 
</lifecycle> 
• Existem 4 escopos a partir do JSF 2: 
▫ @RequestScoped: os beans gerenciáveis de escopo 
request são instanciados e permanecem disponíveis 
durante uma mesma requisição HTTP. 
▫ @ViewScoped: os beans gerenciáveis de escopo view 
permanecem disponíveis enquanto o usuário permanecer 
em uma mesma página de uma aplicação. 
▫ @SessionScoped: os beans gerenciáveis de escopo 
session são salvos na sessão HTTP de um usuário. 
▫ @ApplicationScoped: os beans gerenciáveis de escopo 
application permanecem disponíveis enquanto a aplicação 
estiver no ar, e podemser acessados por todos os usuários 
da aplicação. 
Escopos do Managed-Bean 
Flash 
• Conceito originário do framework Ruby on 
Rails. 
• Fornece um meio de passar objetos entre as 
visões de usuário. 
• Um objeto que use flash poderá ser acessado na 
próxima visão, mesmo após um redirect. 
• Permite preservar mensagens definidas no 
managed bean, mesmo após um redirect. 
Flash 
@ManagedBean 
public class AutomovelBean { 
 ... 
 public String insere() { 
 ... 
 Flash flash = FacesContext.getCurrentInstance(). 
 getExternalContext().getFlash(); 
 flash.setKeepMessages(true); 
 FacesContext.getCurrentInstance().addMessage(null, 
 new FacesMessage(FacesMessage.SEVERITY_INFO, 
 "Automóvel inserido com sucesso.", null)); 
 return "/automovel/lista?faces-redirect=true"; 
 } 
 ... 
} 
 
Action e ActionListener 
• Action 
▫ Usado para executar a lógica da aplicação. 
• ActionListener 
▫ Serve para observarmos eventos de tela. 
▫ Escutar as ações do usuário, mas sem objetivo de 
negócio. 
▫ Associado a método público e void. 
▫ Há opção de ter parâmetro ou não receber um 
javax.faces.event.ActionEvent. 
Action e ActionListener 
<h:commandButton id="botaoSalvar" value="Salvar" 
 actionListener="#{automovelBean.listener}“ 
 action="#{automovelBean.salvar(automovel)}"/> 
public void listener(ActionEvent event){ 
 UIComponent source = event.getComponent(); 
 System.out.println("Ação executada no componente " 
 + source.getId()); 
} 
Action e ActionListener 
• Outra forma de associar uma ActionListener com a 
ação: 
▫ Através da tag f:actionListener. 
▫ Permite especificar mais de um listener. 
▫ Serão executados na ordem especificada. 
▫ Vincula a ação com classes que implementam a 
interface ActionListener. 
▫ Uma mesma ação pode ter vários listeners. 
<h:commandButton id="botaoSalvar" value="Salvar" 
 action="#{automovelBean.salvar(automovel)}"> 
 <f:actionListener type="facesmotors.LoggerActionListener"/> 
 <f:actionListener type="..."/> 
</h:commandButton> 
Action e ActionListener 
<h:commandButton id="botaoSalvar" value="Salvar" 
 action="#{automovelBean.salvar(automovel)}"> 
 <f:actionListener type="facesmotors.LoggerActionListener"/> 
 <f:actionListener type="..."/> 
</h:commandButton> 
public class LoggerActionListener implements ActionListener{ 
 @Override 
 public void processAction(ActionEvent event) 
 throws AbortProcessingException { 
 UIComponent source = event.getComponent(); 
 System.out.println("Ação executada no componente " 
 + source.getId()); 
 } 
} 
Action e ActionListener 
• Usar ActionListener para executar algo antes da 
ação de negócio, como: 
▫ Logar algo 
▫ setar alguma propriedade via 
<f:setPropertyActionListener>. 
▫ Acessar o componente que chamou a ação 
(disponível no parâmetro ActionEvent). 
• ActionListerner não permite navegação após sua 
execução (retorno void). 
• ActionListener sempre ocorre antes de Action. 
Action e ActionListener 
• ActionListener sempre ocorre antes de Action: 
<h:commandLink value="submit" actionListener="#{bean.listener1}" 
action="#{bean.submit}"> 
<f:actionListener type="com.example.SomeActionListener" /> 
<f:setPropertyActionListener target="#{bean.property}" value="some"/> 
</h:commandLink> 
Ordem de execução: 
1. Bean#listener1() 
2. SomeActionListener#processAction() 
3. Bean#setProperty() 
4. Bean#submit() 
setPropertyActionListener 
Normalmente <f:setPropertyActionListener ...> é usado para enviar 
uma variável associada a uma linha de uma dataTable como em: 
... 
<h:dataTable value="#{produtoBean.produtos}" var="produto"> 
 <h:column> 
 <h:outputText value="#{produto.descricao}" /> 
 </h:column> 
 <h:column> 
 <h:outputText value="#{produto.valor}" /> 
 </h:column> 
 <p:commandButton value="Detalhes" 
actionListener="#{produtoBean.detalhar}"> 
 <f:setPropertyActionListener target="#{produtoBean.produto}" 
value="#{produto}"/> 
 </p:commandButton> 
</h:dataTable> 
... 
Substituir construções assim: 
<h:commandLink value="Próxima página" 
action="#{bean.proxPagina}" /> 
public String proxPagina() { 
 return "prox_pagina"; 
} 
Por: 
<h:commandLink value="Próxima página" action="prox_pagina" /> 
Melhor ainda seria evitar a “navegação através de POST” assim: 
<h:link value="Próxima página" outcome="prox_pagina" /> 
Facelets 
• Facelets é um framework de criação de templates de 
páginas JSF. É um projeto open source. 
 
• O Facelets permite criar uma página-modelo 
(template), que será base estrutural e visual para as 
demais páginas JSF do sistema. 
 
• Essa página-modelo (template) é uma página 
normal em XHTML, com algumas tags específicas 
do Facelets. 
 
• Boa prática: 
▫ Criar templates na pasta: /WEB-INF/templates 
 
Introdução a Facelets 
• Já vem embutido a partir do JSF 2.0. 
• Apenas adicione nas páginas: 
 
Facelets 
<?xml version="1.0" encoding="ISO-8859-1" ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
 xmlns:f="http://java.sun.com/jsf/core" 
 xmlns:h="http://java.sun.com/jsf/html" 
 xmlns:p="http://primefaces.org/ui" 
 xmlns:ui="http://java.sun.com/jsf/facelets"> 
<h:head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> 
<title>Template de Pagina JSF</title> 
</h:head> 
<h:body> 
</h:body> 
</html> 
Template usada por várias páginas 
• Na figura abaixo temos um template de página: 
 
Introdução a Facelets 
Criando uma template: ui:insert 
• Utilizado para posicionar os trechos dinâmicos. 
• O atributo name desse componente é utilizado 
para nomear os trechos dinâmicos. 
<div id="pagina"> 
 <div id="cabecalho"> 
 <ui:insert name=“cabecalho" > 
 </ui:insert> 
 </div> 
 
 <div id="menu"> 
 <ui:insert name=“menu" > 
 </ui:insert> 
 </div> 
 
 <div id="conteudo"> 
 <ui:insert name=“conteudo" > 
 </ui:insert> 
 </div> 
 
 <div id="rodape"> 
 <ui:insert name=“rodape" > 
 </ui:insert> 
 </div> 
</div> 
Criando uma template 
Usando a Template – ui:composition 
 <ui:composition template="/WEB-INF/templates/template.xhtml"> 
 
 </ui:composition> 
• Quando criamos uma página que irá usar uma 
template precisamos especificar qual será o arquivo 
que possui o template, para isto iremos utilizar a tag 
composition. 
• Todo conteúdo não contido na tag 
<ui:composition> será descartado pelo JSF no 
processo de construção da tela. 
Usando a Template – ui:define 
<ui:composition template="/WEB-INF/templates/template.xhtml"> 
 <ui:define name="conteudo"> 
 <h1>Cadastro de Aluno</h1> 
 </ui:define> 
</ui:composition> 
• O conteúdo de um trecho dinâmico pode ser 
definido através do componente <ui:define>. 
• Ele possui o atributo name que é utilizado para 
indicar qual trecho dinâmico do template queremos 
definir. 
• Se o conteúdo de um trecho dinâmico não for 
definido, o JSF utilizará o conteúdo existente no 
corpo da tag <ui:insert> definido no template. 
Aviso Importante 
• Quando utilizamos um template não há 
necessidade de especificar novamente as tags 
h:head, h:body ou qualquer outra tag que já 
tem no template, pois está página agora terá 
as mesmas tags do template para montar seu 
layout. 
Template usada por várias páginas 
<ui:insert name="x"> 
<ui:composition> 
 <ui:define name="x"> 
</ui:composition> 
Modularização 
• Trechos estáticos ou dinâmicos definidos em um 
template possuemposição fixa. 
• Em determinadas situações, é necessário tornar 
flexível o posicionamento de um determinado 
trecho. 
• Exemplo: 
▫ Formulário de contato deve ser exibido em 
posições diferentes nas telas da aplicação. 
▫ Em algumas telas o formulário aparecerá no topo 
e em outras ele aparecerá no centro. 
Modularização 
Fragmento de página a ser inserida 
com ui:composition 
• A melhor abordagem é definir o formulário de 
contato, separadamente, em um arquivo 
XHTML. 
• O código XHTML que define o formulário de 
contato deve ser inserido no corpo da tag 
<ui:composition>. 
Fragmento de página a ser inserida 
com ui:composition 
Adicionar fragmento com ui:include 
... 
<ui:include src="/formulario-de-contato.xhtml"/> 
... 
Usando parâmetros no fragmento a 
ser inserido 
Enviando parâmetros para o fragmento 
de página a ser adicionado 
... 
<ui:include src ="/lista-livros.xhtml"> 
 <ui:param name="livros" value="#{livrosBean.livrosMaisVend}"/> 
</ui:include > 
... 
Modularização 
<ui:composition> 
<ui:include> 
 <ui:param> 
</ui:include> 
 
Exercício 
• Altere o último trabalho para que ele use 
facelets.

Outros materiais