JSF e o PrimeFaces - Parte 1
Este artigo abordará alguns recursos bastante interessantes e úteis do JavaServer Faces. Ao longo do texto, estudaremos em detalhes o suporte do JSF a internacionalização, a construção de páginas web baseadas em templates e a interceptação e tratamento, fase a fase, de uma requisição de usuário, dentro de seu ciclo de vida padrão.
Em que situação o tema é útil:
O tema deste artigo é útil para os desenvolvedores web que buscam entender melhor os conceitos que compõem a tecnologia JavaServer Faces. O objetivo é dar solidez de conceito através da aplicaçao prática de todos os fundamentos essenciais da tecnologia, e eliminar com isto uma série de dúvidas ou inseguranças sobre seu real funcionamento, nos bastidores.
JSF e o PrimeFaces – Parte 2:
Este artigo trata de temas muito importantes dentro do desevolvimento de aplicações em Java para a Web. O tratamento das fases de uma requisição web nos dá uma grande flexibilidade no desenvolvimento de soluções web, pois podemos assim interceptar e tratar cada momento particular de uma requisição de usuário, desde sua chegada até a finalização de seu processamento, que resultará em uma resposta. Ao mesmo tempo, a internacionalização é um poderoso recurso que nos possibilita ampliar o número de usuários de nossos sistemas, através da sua disponibilização em diversos idiomas. Por fim, o uso de templates reduz consideravelmente a replicação de código, tornando o design e o desenvolvimento de soluções web mais organizado, enxuto e legível.
No artigo anterior, falamos sobre boa parte dos principais conceitos do JavaServer Faces, além da própria preparação do ambiente de desenvolvimento. Abordamos desde a construção das páginas web até a comunicação destas com entidades específicas da tecnologia JSF, denominadas beans gerenciados. Em detalhes, estudamos estas unidades de código, que representam a ligação entre páginas e o restante do sistema. Estudamos também seu ciclo de vida e entendemos a razão do termo “gerenciado” que os classifica, dado que toda a existência desses objetos em memória é controlada exclusivamente pelo container web – ou servidor de aplicações.
O primeiro artigo também nos deu detalhes sobre o comportamento de cada requisição de usuário, desde que chega ao sistema até o momento em que tem seu processamento finalizado e, então, uma resposta correspondente, a ser enviada de volta para o navegador web de onde a requisição se originou.
Abordamos ainda as estratégias disponíveis para estabelecer o fluxo entre as páginas de um sistema, apresentando a estratégia de mapeamento através de regras de navegação, a partir de outcomes (saídas) pré-definidas.
Finalizamos o artigo com uma breve introdução à API do JSF, que nos permite recuperar o contexto de cada requisição de usuário e, a partir dela, de objetos fundamentais dentro da arquitetura, como aquele que representa a aplicação, os próprios beans gerenciados, a raiz da árvore de componentes de cada página, dentre outros.
Neste artigo, estudaremos outros conceitos elementares deste poderoso framework. Começaremos ilustrando o suporte a internacionalização, principalmente mostrando o quanto é simples e direto trabalhar com este importante recurso em projetos baseados em JSF. Então, passaremos para o tratamento de fases de uma requisição de usuário, levantando e detalhando tudo o que precisamos fazer para que sejamos capazes de interceptar uma requisição em diversos momentos de sua existência na memória. Por fim, apresentaremos o uso de templates, um recurso fundamental no desenho da interface com o usuário em soluções web baseadas em Java. Ao longo de todo o texto, rechearemos o código com componentes da biblioteca PrimeFaces, comentando a respeito de algumas dessas estruturas.
Internacionalização
Um recurso bem interessante do JSF é o suporte a internacionalização. De uma forma bastante direta e simples, o JSF permite que atendamos mais de um idioma em nossas soluções web, e mostraremos como fazê-lo a partir de agora.
O primeiro passo para isso é criarmos arquivos de propriedades que conterão os rótulos que a aplicação exibirá. Assim como nos arquivos de DRM (Data Resource Mapping) em plataformas operacionais móveis como Symbian, ou ainda nos arquivos de recursos de outras mais modernas, como o Android, a estratégia em Java para a Web se repete: através de uma chave única, representamos um mesmo rótulo em idiomas diversos.
Observe a Listagem 1. Nela, observamos o conteúdo de um arquivo de propriedades de nome messages_pt.properties. Esses arquivos guardam elementos do tipo chave-valor, que são carregados em instâncias de mapas (como java.util.HashMap) em tempo de execução. Veja a Listagem 1 e observe o valor guardado pelo identificador “login_username”. Trata-se do texto “Usuário”. Em nossas páginas web, sempre utilizaremos os identificadores definidos nesses arquivos de propriedades ao invés do texto direto que desejamos ver impresso, deixando a recuperação do valor correspondente delegada ao framework.
Listagem 1. Arquivo de linguagem para português (messages_pt.properties).
# Página de login
login_usename=Usuário
login_passwd=Senha
login_action_go=Entrar
login_action_clean=Limpar
#Login outcomes
OUTCOME_LOGIN_SUCCESS=loginSuccess
OUTCOME_LOGIN_FAILURE=loginFailed
Listagem 2. Arquivo de linguagem para inglês (messages_en.properties).
# Login page
login_usename=Username
login_passwd=Password
login_action_go=Login
login_action_clean=Clean
#Login outcomes
OUTCOME_LOGIN_SUCCESS=loginSuccess
OUTCOME_LOGIN_FAILURE=loginFailed
Na Listagem 2, observamos outro arquivo de propriedades em que os mesmos rótulos encontrados na Listagem 1 recebem, agora, outros valores, traduzidos desta vez para a língua inglesa. O arquivo, neste caso, é nomeado como messages_en.properties. O leitor atento deve ter identificado que existe uma nomenclatura padrão para nomear estes arquivos de linguagem. Através do sufixo apropriado, identificamos a linguagem para a qual os rótulos de uma aplicação serão traduzidos naquele arquivo. De maneira geral, o formato a ser respeitado é o que se segue:
<nome do arquivo>_<idioma>.properties
Neste formato, o <idioma> deve ser representado através de duas letras. A Tabela 1 exibe alguns dos identificadores de idiomas que podem ser utilizados.
Linguagem |
Identificador |
Português |
pt |
Inglês |
en |
Alemão |
de |
Francês |
fr |
Italiano |
it |
Japonês |
ja |
Coreano |
ko |
Espanhol |
es |
Sueco |
sv |
Tabela 1. Identificadores de localização.
Uma vez criados os arquivos de linguagem, o próximo passo é configurarmos o suporte a múltiplos idiomas em nossa solução. Esta é uma característica do JavaServer Faces e deve ser, portanto, mapeada no arquivo de configuração do framework (faces-config.xml). Examinemos a Listagem 3.
Observe o marcador resource-bundle. Nele, definimos um pacote de recursos e o identificamos pela variável labels. Esta variável será usada para acessar todos os rótulos definidos no arquivo de linguagem selecionado pela aplicação, tanto no código-fonte quanto nas páginas web da aplicação.
Foi definida, também, a base do nome dos arquivos de linguagem. Como o próprio nome sugere, este texto corresponderá ao prefixo do nome completo do arquivo, e o seu sufixo será determinado de acordo com a configuração da máquina que hospeda o navegador que está acessando a aplicação. Em configurações regionais norte-americanas, por exemplo, o nome do arquivo de linguagem será uma combinação do nome-base com o sufixo _en, resultando no arquivo br.com.devmedia.jm.messages_en.properties.
Ainda sobre arquivos de linguagem, definimos também a localização padrão e todas aquelas que devem ser suportadas dentro da aplicação. Na Listagem 3, podemos observar esta configuração através dos marcadores locale-config, default-locale e supported-locale. Uma solução web pode ter uma localização padrão e quantas localizações adicionais (suportadas) forem necessárias.
Além de contar com a própria plataforma para, automaticamente, selecionar o arquivo de linguagens correto de acordo com a configuração da máquina cliente, podemos modificar programaticamente a localização a ser considerada para apresentar as mensagens ao usuário. Verificaremos, a partir de agora, como utilizar esses rótulos em nossas páginas web e também como manipular o código-fonte para, programaticamente, alterar a localização e, com isso, o idioma em que as mensagens são exibidas para o usuário.
A partir da declaração que fizemos no arquivo de configuração do JSF, e que pudemos ver na Listagem 3, podemos utilizar a variável labels para acessar todo e qualquer rótulo definido nos arquivos de linguagem. Observe o emprego desta variável na Listagem 4, para definir os textos dos rótulos dos campos de usuário e senha da página de login de nossa aplicação-guia, e também dos botões que disparam as ações de limpeza de dados e login. Pelos identificadores, somos capazes de acessar os valores por eles referenciados. Desta maneira, separamos a declaração de mensagens do sistema da estruturação das páginas propriamente ditas.
Listagem 3. Arquivo de configuração do JSF.
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<lifecycle>
<phase-listener>br.com.devmedia.jm.listeners.LoginListener</phase-listener>
</lifecycle>
<application>
<resource-bundle>
<var>labels</var>
<base-name>br.com.devmedia.jm.messages</base-name>
</resource-bundle>
<locale-config>
<default-locale>pt</default-locale>
<supported-locale>en</supported-locale>
</locale-config>
</application>
<!-- Declaração das regras de navegação, apresentadas no primeiro artigo da série -->
<!-- Declaração dos beans gerenciados, apresentada no primeiro artigo da série -->
</faces-config>
Listagem 4. Acessando rótulos de um arquivo de linguagem em uma página web.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>#{labels.login_title}</title>
<h:outputStylesheet library="css" name="estilos.css" />
</h:head>
<h:body>
<h:form>
<p:panel id="loginPanel" style="margin: 0px auto; vertical-align: top;
width: 500px; margin-top: 300px;" >
<p:panelGrid columns="2" id="loginFieldsPanel" style="width: 450px;
margin: 0 auto; vertical-align: central">
<h:outputLabel value="#{labels.login_usename}" />
<p:inputText value="#{mBLogin.user.username}" id="usrname" />
<h:outputLabel value="#{labels.login_passwd}" />
<p:password value="#{mBLogin.user.password}" id="passwd" />
</p:panelGrid>
<p:panelGrid columns="3" id="loginActionPanel" style="width: 450px;
margin: 0 auto; vertical-align: central">
<p:commandButton action="#{mBLogin.doLogin()}" id="actionLogin"
value="#{labels.login_action_go}" ajax="false" />
<p:commandButton action="#{mBLogin.cleanFields()}" id="actionClean"
value="#{labels.login_action_clean}" ajax="true"
update="usrname passwd" />
<p:commandButton actionListener="#{mBLanguage.changeLanguage}" id="actionLang"
value="#{labels.login_action_change_switch_pt_en}" ajax="false" />
</p:panelGrid>
</p:panel>
</h:form>
</h:body>
</html>
Outra maneira de carregarmos uma referência para um arquivo de linguagem é utilizarmos um componente do JSF de dentro da própria página, conforme exibido na Listagem 5. Por esta listagem, observamos o uso do componente <f:loadBundle>, que pertence à biblioteca core do JSF.
Listagem 5. Carregando um arquivo de linguagem em uma página web.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>#{labels.home_title}</title>
<h:outputStylesheet library="css" name="estilos.css" />
<f:loadBundle var="labels" basename="br.com.devmedia.jm.messages" />
</h:head>
<h:body>
<p:accordionPanel id="home_accordion" >
<p:tab title="" ></p:tab>
</p:accordionPanel>
</h:body>
</html>
De uma maneira geral, navegadores incluem a região de referência no atributo Accept-Language do cabeçalho HTTP, e a implementação JSF tratará de identificar a melhor opção dentre aquelas declaradas como suportadas na lista de locais (Locale) da aplicação. Para obter mais informações sobre o marcador de linguagens, utilizado em cabeçalhos de requisições sobre o protocolo HTTP, consulte a seção Links.
Até aqui, vimos como trabalhar com arquivos de linguagem, carregando-os tanto programaticamente quanto declarativamente. Mas, e se quisermos trocar o idioma da página já com o sistema em execução? Veremos, agora, que isso é possível e, mais que isso, é bastante simples.
Primeiramente, é preciso entender que toda localização (ou configuração regional) pode ser representada, em Java, através de uma instância da classe java.util.Locale. Em JSF, portanto, basta sabermos qual é a entidade responsável por encapsular a configuração regional que será utilizada nas páginas de nosso sistema.
A API do JSF nos dá a classe javax.faces.component.UIViewRoot, que representa a raiz da árvore de componentes da página web em exibição. Esta classe contém, internamente, um atributo do tipo java.util.Locale ...
Confira outros conteúdos:
Black November
Desconto exclusivo para as primeiras 200 matrículas!
Pagamento anual
12x no cartão
De: R$ 69,00
Por: R$ 54,90
Total: R$ 658,80
Garanta o desconto
- Formação FullStack Completa
- Carreira Front-end I e II, Algoritmo e Javascript, Back-end e Mobile
- +10.000 exercícios gamificados
- +50 projetos reais
- Comunidade com + 200 mil alunos
- Estude pelo Aplicativo (Android e iOS)
- Suporte online
- 12 meses de acesso
Pagamento recorrente
Cobrado mensalmente no cartão
De: R$ 79,00
Por: R$ 54,90 /mês
Total: R$ 658,80
Garanta o desconto
- Formação FullStack Completa
- Carreira Front-end I e II, Algoritmo e Javascript, Back-end e Mobile
- +10.000 exercícios gamificados
- +50 projetos reais
- Comunidade com + 200 mil alunos
- Estude pelo Aplicativo (Android e iOS)
- Suporte online
- Fidelidade de 12 meses
- Não compromete o limite do seu cartão
<Perguntas frequentes>
Nossos casos de sucesso
Eu sabia pouquíssimas coisas de programação antes de começar a estudar com vocês, fui me especializando em várias áreas e ferramentas que tinham na plataforma, e com essa bagagem consegui um estágio logo no início do meu primeiro período na faculdade.
Estudo aqui na Dev desde o meio do ano passado!
Nesse período a Dev me ajudou a crescer muito aqui no trampo.
Fui o primeiro desenvolvedor contratado pela minha
empresa. Hoje eu lidero um time de desenvolvimento!
Minha meta é continuar estudando e praticando para ser um
Full-Stack Dev!
Economizei 3 meses para assinar a plataforma e sendo sincero valeu muito a pena, pois a plataforma é bem intuitiva e muuuuito didática a metodologia de ensino. Sinto que estou EVOLUINDO a cada dia. Muito obrigado!
Nossa! Plataforma maravilhosa. To amando o curso de desenvolvimento front-end, tinha coisas que eu ainda não tinha visto. A didática é do jeito que qualquer pessoa consegue aprender. Sério, to apaixonado, adorando demais.
Adquiri o curso de vocês e logo percebi que são os melhores do Brasil. É um passo a passo incrível. Só não aprende quem não quer. Foi o melhor investimento da minha vida!
Foi um dos melhores investimentos que já fiz na vida e tenho aprendido bastante com a plataforma. Vocês estão fazendo parte da minha jornada nesse mundo da programação, irei assinar meu contrato como programador graças a plataforma.
Wanderson Oliveira
Comprei a assinatura tem uma semana, aprendi mais do que 4 meses estudando outros cursos. Exercícios práticos que não tem como não aprender, estão de parabéns!
Obrigado DevMedia, nunca presenciei uma plataforma de ensino tão presente na vida acadêmica de seus alunos, parabéns!
Eduardo Dorneles
Aprendi React na plataforma da DevMedia há cerca de 1 ano e meio... Hoje estou há 1 ano empregado trabalhando 100% com React!
Adauto Junior
Já fiz alguns cursos na área e nenhum é tão bom quanto o de vocês. Estou aprendendo muito, muito obrigado por existirem. Estão de parabéns... Espero um dia conseguir um emprego na área.
Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.