dsweb-jsf-parte4.pdf
-
Upload
adriano-paula -
Category
Documents
-
view
35 -
download
0
Transcript of dsweb-jsf-parte4.pdf
Desenvolvimento de Software
para WEB
JSF (JavaServer Faces) – Parte 4
Prof. Regis Pires Magalhães
Agradecimentos
• Agradecemos ao Prof. Fábio Dias (UFC Quixadá) por ter gentilmente cedido seus slides para adaptação e uso nesta disciplina.
Conversão e Validação
• A conversão trata da transformação de dados de formulários em objetos java.
• A validação trata da checagem de corretude dos resultados da conversão.
• Neste sentido, alguns passos são efetuados antes de atualizar o modelo de dados: ▫ A idéia é impedir que valores inválidos.
cheguem até a lógica de negócio.
Introdução
• Para visualizar melhor o processo de conversão e validação, vamos visualizar em detalhes os passos seguidos desde a entrada de dados em um formulário até o preenchimento do bean com eles:
Visão Geral do Processo
Visão Geral do Processo - Exemplo
Conversão
• Os dados submetidos por um usuário sempre são do tipo String
• Contudo, muitos desses dados devem ser transformados em outros tipos para serem armazenados no Modelo
• Se no Model o valor for um tipo primitivo ou um objeto Integer/Double/Float/BigInteger/BigDecimal, a conversão é direta
• Caso contrário, é necessário especificar um conversor: ▫ Pode ser um conversor básico já existente
Ex: datas e números
▫ Pode ser um conversor criado pelo desenvolvedor
Introdução
• f:convertNumber: é um dos conversores básicos disponibilizados pela JSF para exibir números formatados.
• f:convertDateTime: é utilizada para exibir datas e horas segundo uma formatação. Os padrões utilizados são os da SimpleDateFormat.
• Também são usados para formatar dados exibidos.
Conversores Básicos
Conversores Básicos
<h:inputText value="#{pagamentoBean.total}“>
<f:convertNumber minFractionDigits=“5"/>
</h:inputText>
<h:inputText value="#{pagamentoBean.numCartao}"/>
<h:inputText value="#{pagamentoBean.dataCartao}">
<f:convertDateTime pattern=“dd/MM/yyyy"/>
</h:inputText>
• type pode ser: number(default), currency ou percent
Converter Number
<h:outputText value="#{bean.inteiro}">
<f:convertNumber type="percent"/>
</h:outputText>
<h:outputText value="#{bean.inteiro}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
• Se true, apenas a parte inteira é levada em consideração. Default é false.
Converter Number
<h:inputText value="#{bean.fracionario}">
<f:convertNumber integerOnly="true"/>
</h:inputText>
<h:inputText value="#{bean.fracionario}">
<f:convertNumber pattern="##0.00"/>
</h:inputText>
• Aplica o padrão de formatação no número similar ao da
DecimalFormat.
• Número máximo/mínimo de casas decimais
Converter Number
<h:outputText value="#{bean.fracionario}">
<f:convertNumber maxFractionDigits="4"/>
</h:outputText>
<h:outputText value="#{bean.fracionario}">
<f:convertNumber minFractionDigits="4"/>
</h:outputText>
• type: Especifica o tipo que será exibido, date, time ou both.
Converter Date Time
<h:outputText value="#{bean.data}">
<f:convertDateTime type="date" dateStyle="short" />
</h:outputText>
• A tabela abaixo mostra alguns atributos utilizados pela tag f:convertDateTime
Converter Date Time
Atributo Descrição
type date (default), time ou both
dateStyle default, short, medium, long, or full
timeStyle default, short, medium, long, or full
pattern Padrão de formatação similar ao da SimpleDateFormat
locale Localidade de onde os padrões devem ser buscados
Valor Exemplo
short 30/05/11
medium 30/05/2011
long 30 de Maio de 2011
full Segunda-feira, 30 de Maio
de 2011
Valor Exemplo
short 15:01
medium 15:01:58
long 15h1min58s BRST
full 15h01min58s BRST
Converter Date Time
<h:outputText value="#{bean.data}">
<f:convertDateTime pattern="dd.MM.yyyy HH:mm" />
</h:outputText>
Converter Date Time
<h:inputText value="#{bean.data}">
<f:convertDateTime type="date" dateStyle="short" />
</h:inputText>
<h:inputText value="#{bean.data}">
<f:convertDateTime pattern=“dd/MM/yyyy" />
</h:inputText>
• Quando um erro de conversão/validação ocorre, as seguintes ações são tomadas: ▫ O componente cuja conversão/validação falhou
posta uma mensagem e declara-se como inválido ▫ Pode-se usar tags para exibir esta mensagem
h:message Exibe mensagem para um componente em particular
h:messages Exibe mensagens para todos os componentes
• A implementação JSF recarrega a página atual após a fase de validações
Tratando Erros
• Caso algum campo possua erro, deve-se mostrar a mensagem de erro ao lado do campo.
Tratando Erros - Mensagens Separadas
<h:panelGrid columns="2">
<h:outputText value="Total"/>
<h:panelGroup>
<h:inputText id="total“ value="#{pagamento.total}">
<f:convertNumber minFractionDigits=“5" />
</h:inputText>
<h:message for="total"/>
</h:panelGroup>
Tratando Erros - Mensagens Separadas
<h:outputTextvalue="Número do Cartão:"/>
<h:inputText value="#{pagamento.numeroCartao}" />
<h:outputTextvalue="Data de Validade (mês/ano):"/>
<h:panelGroup>
<h:inputText id="data"value="#{pagamento.dataCartao}">
<f:convertDateTime pattern=“dd/MM/yyyy" />
</h:inputText>
<h:message for="data“/>
</h:panelGroup>
<h:commandButton value="Enviar" action="sucesso"/>
</h:panelGrid>
Tratando Erros - Mensagens Separadas
Tratando Erros - Mensagens Juntas
<fieldset>
<legend>Pagamento</legend>
<h:messages style="color: red"/>
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Total"/>
<h:panelGroup>
<h:inputText id="total" value="#{pagamento.total}">
<f:convertNumber minFractionDigits=“5" />
</h:inputText>
</h:panelGroup>
...
</h:panelGrid>
</h:form>
</fieldset>
Tratando Erros - Mensagens Juntas
<h:inputText id="total" value="#{pagamento.total}"
label=“Valor inválido">
<f:convertNumber minFractionDigits=“5"/>
</h:inputText>
<h:message for="total"/>
<h:inputText id="data"
value="#{pagamento.dataCartao}" label="Data
inválida">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:inputText>
<h:message for="data"/>
Modificando Mensagens de Erro
Modificando Mensagens de Erro
<h:inputText id="total" value="#{pagamento.total}"
converterMessage=“Valor inválido">
<f:convertNumber minFractionDigits=“5"/>
</h:inputText>
<h:message for="total"/>
<h:inputText id="data"
value="#{pagamento.dataCartao}”
converterMessage="Data inválida.">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:inputText>
<h:message for="data"/>
Modificando Mensagens de Erro
Modificando Mensagens de Erro
Validação
• O papel principal da validação é proteger o modelo:
▫ A validação ocorre em uma fase anterior à da atualização do modelo
▫ O modelo só é atualizado quando os dados estiverem devidamente validados
• O uso de validadores é similar ao de conversores:
▫ Adiciona-se uma tag f:validate___ no corpo do campo que se deseja validar
Introdução
• Existem alguns validadores pré-definidos que podem ser incluídos no corpo das tags:
Validadores Pré-Definidos
Atributo Atributos Funcionamento
f:validateDoubleRange minimum, maximum Define uma faixa de valores double na
qual um valor deve estar contido
f:validateLongRange minimum, maximum Define uma faixa de valores long na
qual um valor deve estar contido
f:validateLength minimum, maximum Define uma faixa de tamanho de uma
string
• Adicionalmente, pode-se especificar que certos campos
são requeridos através do uso do atributo required
Validadores Pré-Definidos
<h:inputText id="total" value="#{pagamento.total}"
validatorMessage="Valor total não pode ser menor que 5">
<f:validateLongRange minimum="5"/>
</h:inputText>
<h:inputText value="#{pagamento.numeroCartao}"
validatorMessage="Número do cartão deve possuir 13 caracteres.">
<f:validateLength minimum="13"/>
</h:inputText>
<h:inputText id="data" value="#{pagamento.dataCartao}"
required="true" requiredMessage="Campo data é obrigatório."/>
Mensagem de
validação personalizada Mensagem de requerimento
personalizada
Tamanho de Strings e Faixa de Valores Numéricos
• Em certos casos, é necessário deixar a validação de lado:
▫ Usuário clica no botão voltar ou cancelar
▫ Não deve ocorrer validação
• Em situações como essa, o comando deve ser executado antes da validação
▫ Ex: definir o atributo immediate da tag do botão para true
Pulando a Validação/Conversão
<h:commandButton value="Cancelar"
action="cancelar" immediate="true"/>
Resumindo
• converterMessage: especificar que mensagem queremos que apareça caso ocorra um erro de conversão.
• requiredMessage: especificar que mensagem queremos que apareça quando o campo é obrigatório mas não foi informado.
• validatorMessage: especificar que mensagem queremos que apareça caso ocorra um erro de validação.
Internacionalização
• Ao implementar uma aplicação, é uma boa prática definir todas as strings em um arquivo central ▫ Facilita a manutenção
▫ Auxilia na internacionalização
• Para isso, JSF faz uso de um arquivo de propriedades ▫ Arquivo texto com extensão .properties
▫ Neste arquivo cada mensagem é mapeada na forma chave=valor
▫ Chave é o nome lógico
▫ Valor é o valor real da mensagem que será exibida
Arquivo de Mensagens
nome_Funcionario=Nome do funcionário:
erro.incluir.cliente=Erro ao incluir um cliente!
• Criar os arquivos de mensagens para cada linguagem dentro de um pacote próprio para isso, por exemplo resources ou idiomas: ▫ Messages.properties
▫ Messages_pt_BR.properties
▫ Messages_en.properties
▫ Messages_es.properties
▫ Etc
• Dentro de cada arquivo no campo valor, é uma boa prática usar um padrão para nomeação das chaves. Por exemplo, use o padrão de chave nome_da_tela_campo ou nome_da_tela_mensagem.
• Separe os nomes que compõe as chaves por “_” ou “.”.
Arquivo de Mensagens
nome_Funcionario=Nome do funcionário:
erro.incluir.cliente=Erro ao incluir um cliente!
• Vamos definir uma variável fixa que represente o arquivo de mensagens
▫ Todas as páginas podem acessá-la
▫ É configurada no faces-config.xml
Arquivo de Mensagens
<application> ... <resource-bundle> <base-name>br.ufc.mensagens</base-name> <var>msgs</var> </resource-bundle> ... </application>
faces-config.xml
Arquivo de mensagens
Arquivo de mensagens
automovel_descricao = Descrição do Automóvel:
erro.incluir.cliente = Erro ao incluir um cliente!
erro.descricao.invalida = Descrição inválida.
No pacote br.ufc, criar o arquivo: mensagens.properties:
mensagens_pt_BR.properties
label_ano_fabricacao = Ano de Fabricação label_ano_modelo = Ano do Modelo label_preco = Preço label_km = Kilometragem label_obs = Observações
exemplo.xhtml ... #{msgs.label_ano_fabricacao}: <h:inputText label="#{msgs.label_ano_fabricacao}" value="#{automovelBean.automovel.anoFabricacao}"/> #{msgs.label_ano_modelo}: <h:inputText label="#{msgs.label_ano_modelo}" value="#{automovelBean.automovel.anoModelo}"/> #{msgs.label_preco}: <h:inputText label="#{msgs.label_preco}" value="#{automovelBean.automovel..preco}" /> ...
• O arquivo correspondente à localidade atual é carregado.
▫ Se o arquivo correspondente não existir, é utilizado o arquivo padrão.
• Pode-se modificar a localidade em 2 níveis para uma página:
▫ Uso do elemento View: Adicionando um atributo locale na tag <f:view locale=“pt_BR”>.
▫ Via programação:
FacesContext context = FacesContext.getCurrentInstance();
context.getViewRoot().setLocale(new Locale(“pt”, “BR”));
Arquivo de Mensagens
• Uma vez carregado o arquivo, pode-se acessá-lo na página através de binding expressions:
Arquivo de Mensagens
<h:outputText value="#{msgs.nome_Funcionario}"/>
<h:inputText value=""/><br>
<h:outputText value="#{msgs['erro.incluir.cliente']}"/>
Mensagens contendo o ponto como separador
precisam ser definidas dentro de colchetes
nome_Funcionario=Nome do funcionário:
erro.incluir.cliente=Erro ao incluir um cliente!
• Para acessar o arquivo .properties dentro da classe controller use a classe abaixo:
Arquivo de Mensagens
import java.util.ResourceBundle; import javax.faces.context.FacesContext; public class MensagemUtil { public static String getMensagem(String chave){ FacesContext context = FacesContext.getCurrentInstance(); ResourceBundle bundle = context.getApplication().getResourceBundle(context, "msg"); return bundle.getString(chave); } }
Alterando Idioma Dinamicamente
@ManagedBean(name="idiomaController") @SessionScoped public class IdiomaController { private Locale correnteLocale = new Locale("pt", "BR"); public void setLocalePortugues(){ correnteLocale = new Locale("pt", "BR"); } public void setLocaleIngles(){ correnteLocale = new Locale("en", "US"); } public Locale getCorrenteLocale() { return correnteLocale; } public void setCorrenteLocale(Locale correnteLocale) { this.correnteLocale = correnteLocale; } }
Alterando Idioma Dinamicamente
<h:body> <f:view locale="#{idiomaController.correnteLocale}"> <h:form> ... </h:form> </f:view> </f:body>
• Dentro da página template do facelet coloque:
Validadores Pré-Definidos
<h:inputText id="total" value="#{pagamento.total}"
validatorMessage="#{msg['erro.numero.tamanho.invalido']}">
<f:validateLongRange minimum="5"/>
</h:inputText>
<h:inputText value="#{pagamento.numeroCartao}"
validatorMessage="#{msg['erro.total.valor.menor']}">
<f:validateLength minimum="13"/>
</h:inputText>
<h:inputText id="data" value="#{pagamento.dataCartao}"
required="true" requiredMessage="#{msg['requerido.data']}"/>
Mensagem de
validação personalizada Mensagem de requerimento
personalizada
erro.numero.tamanho.invalido=Número do cartão deve possuir 13 caracteres.
erro.total.valor.menor=Valor total não pode ser menor que 5.
requerido.data=Campo data é obrigatório.
Mensagens padrões do JSF • Estão localizadas no pacote javax.faces, nos arquivos
“Messages_xx_XX.properties”.
▫ Ex: Messages.properties, Messages_pt_BR.properties
Alterando as mensagens padrões
do JSF • Para mudar a mensagem de campo requerido do
JSF, precisamos criar um arquivo chamado Messages_pt_BR.properties dentro de um pacote chamado javax.faces e nesse arquivo colocar um valor para a chave javax.faces.component.UIInput.REQUIRED. ▫ javax.faces.component.UIInput.REQUIRED = Campo obrigatório. Informe-o!
• Com isso, todas as mensagens de campo requerido passariam a usar o texto que nós informamos, e não o texto padrão do JSF.
Exercício
1) Faça um cadastro de pessoa que use
Internacionalização, Conversão e Validação.
Adicione um campo data a classe Pessoa e
inclua no cadastro e atualização. Coloque os
campos como obrigatórios. Coloque todos os
textos das páginas, mensagens de conversão e
validação no arquivo de mensagem.