Você está na página 1de 45

A renovao do JSF Parte 1

Esta a primeira parte de uma srie de dois artigos que, juntos, traro ao leitor uma avaliao das principais caractersticas incorporadas na verso mais recente da especificao JavaServer Faces, integrada Java EE 7.
Esta a primeira parte de uma srie de dois artigos que, juntos, traro ao leitor uma avaliao das principais caractersticas incorporadas na verso mais recente da especificao JavaServer Faces, integrada Java EE 7. Embora a grande maioria das mudanas tenha um carter mais corretivo ou adaptativo, outras constituem um arsenal ainda maior e mais rico de recursos para o desenvolvimento de solues web em Java. Os pontos abordados ao longo da srie no visam, definitivamente, encerrar o assunto, que muito amplo e tem uma gama incrvel de aplicaes. Deste modo, nosso foco ser direcionado quase que totalmente para quatro das mais significativas caractersticas, as chamadas Big Ticket Features.

Em que situao o tema til Este tema bastante relevante para todo desenvolvedor que use a tecnologia Java como alvo em seus sistemas. igualmente til para todo entusiasta de tecnologias web e que, por este motivo, gosta de se manter atualizado em relao ao modo como os frameworks mais populares do mercado evoluem ao longo do tempo. Precisamente no dia 12 de junho de 2013, a Oracle lanou oficialmente a verso 7 da Java Enterprise Edition, a plataforma Java para desenvolvimento de solues web. Esta edio mais evolucionria do que revolucionria, e conta com atualizaes importantes em praticamente todas as especificaes que a compem (Servlets, JPA, Expression Language, CDI, EJB, JMS, JTA, JSP e outras) e tambm com o lanamento de outras inditas, como a API para o protocolo Web Sockets (JSR-356) e a API para processamento de contedo JSON (JSR-353). Alm disso, a Oracle liberou sua implementao de referncia para essas revises atravs de uma nova verso de seu servidor de aplicaes, o GlassFish 4, bem como uma atualizao da IDE NetBeans para a verso 7.3.1, totalmente compatvel com a Java EE 7 e disponvel para download gratuito no site do projeto (veja o endereo para a pgina desta IDE na seo Links). Neste artigo, cobriremos as novidades em torno da especificao JSF, dando maior ateno para as caractersticas consideradas mais profundas, intituladas pelo prprio grupo de trabalho como Big Ticket Features. Ao longo do texto, revisitaremos alguns conceitos fundamentais para facilitar a compreenso do cenrio em que a implementao atual se insere, complementando com exemplos prticos e anlises passo a passo de todo o cdigo-fonte utilizado. Desta forma, esperamos trazer ao leitor um nvel de conforto suficiente para encoraj-lo a utilizar as novidades deste framework em suas prximas aplicaes web ou, ainda, aplic-las nas j existentes. Todo o trabalho realizado para o lanamento do JSF 2.2 originou-se no texto proposto na JSR-344. Boa parte do que se planejou foi cumprido, e o resultado final uma especificao ainda mais madura, completa, poderosa e, por que no dizer, flexvel. Entretanto, os atrasos foram inevitveis, dada toda a turbulncia gerada em torno da tecnologia Java ao longo dos ltimos meses por conta de algumas vulnerabilidades tratadas com grande preocupao e, cabe comentar, certo exagero pela mdia. Tudo isso fez com que parte do trabalho fosse iniciada tardiamente, culminando na reduo do escopo de algumas caractersticas e, em alguns casos, postergao de recursos para edies futuras. A liderana das atividades em torno do JSF 2.2 ficou, mais uma vez, por conta do competente Ed Burns, um engenheiro snior da Oracle frente do desenvolvimento desta especificao desde sua primeira verso. Na seo Links, no final do artigo, convidamos o leitor a visitar a pgina da JSR-344, na qual possvel

conhecermos todos os demais membros da equipe e tudo aquilo que foi proposto e realizado por eles. Esta uma cultura importante, pois nos ajuda a conhecer melhor o papel fundamental exercido pelo JCP (Java Community Process) na evoluo da tecnologia Java em sua totalidade. medida que analisamos o potencial e o nvel de influncia das cabeas por trs de cada JSR (acrnimo para Java Specification Request), bem como as empresas que, direta ou indiretamente, esto envolvidas nas discusses, passamos a entender com muito mais clareza os motivos que fazem com que Java seja lder no mercado mundial por tantos e tantos anos. Embora as chamadas Big Ticket Features sejam poucas (mais precisamente, quatro), envolvem muitos conceitos e imprimem, por este motivo, grande densidade ao tema. Logo, para que consigamos tratar todos os pontos principais com o cuidado necessrio e didtica adequada, dedicaremos todo o restante do artigo para a anlise pontual de cada um deles, reservando o final do texto para algumas concluses importantes acerca de todo o material apresentado. Algumas palavras iniciais sobre o JSF 2.2 JavaServer Faces, como sabemos, uma proposta de framework para a construo da camada de apresentao em sistemas web desenvolvidos em Java. Trata-se de uma dentre as muitas especificaes que, juntas, constituem a plataforma Java EE. Inmeras tecnologias relacionam-se entre si neste universo, e o JavaServer Faces 2.2 tem algumas dependncias diretas que precisam ser conhecidas por todo desenvolvedor, para trazer ao leitor uma viso da posio deste framework no ecossistema global. So elas: JavaServer Pages 2.2, incluindo Expression Language 2.2 (JSR-245); Expression Language 3.0 (JSR-341); Servlet 3.0 (JSR-315); Java Standard Edition, verso 6 (JSR-270); Java Enterprise Edition, verso 6 (JSR-316); Java Beans 1.0.1; JavaServer Pages Standard Tag Library (JSTL) 1.2. Todas essas JSRs esto devidamente documentadas no site do JCP, livres para download e consulta. Novamente, recomendamos ao leitor que dedique algum tempo para conhecer melhor este processo, que dita o passo do progresso da tecnologia Java em seus diversos sabores. Outro ponto que devemos destacar, antes de comear a investigar as novas caractersticas do framework, a limpeza realizada nos seus espaos de nomes (namespaces). O nome Sun foi definitivamente removido das URIs, que foram redefinidas conforme o contedo da Tabela 1. Embora os namespaces antigos ainda sejam vlidos, a recomendao, desde j, para que passemos a evitar seu uso, substituindo-os pelos novos.

Tabela 1. Mudana das URIs dos espaos de nome. Agora que j falamos rapidamente sobre essas mudanas mais gerais da especificao, hora de comearmos a explorar suas principais caractersticas. A primeira Big Ticket Feature: marcadores amigveis HTML Antes de entrarmos no mrito de marcadores HTML-friendly, dedicaremos algumas palavras iniciais para contextualizar o processo de tratamento de requisies de usurio desde o momento em que chegam ao servidor at aquele em que uma resposta enviada para o cliente. Observe o diagrama da Figura 1, que retrata a mquina de estados qual toda requisio JSF submetida. Tudo comea em sua recepo, feita por uma instncia da classe javax.faces.webapp.FacesServlet. Este o controlador frontal do framework, por onde toda entrada (javax.servlet.ServletRequest) chega e toda resposta (genericamente representada pela classe javax.servlet.ServletResponse) despachada. A cada nova requisio, este controlador ficar responsvel por criar um novo objeto de contexto (javax.faces.context.FacesContext) ao qual todas as estruturas relacionadas a ela (e seus respectivos estados) sero vinculadas. Logo em seguida, chega o momento do ciclo de vida ser executado; representado genericamente pela classe javax.faces.lifecycle.Lifecycle, ele encapsula o tratamento de cada um dos seis blocos ilustrados no diagrama da Figura 1 da seguinte maneira: Lifecycle.execute(javax.faces.context.FacesContext): cuida dos cinco primeiros blocos do ciclo de vida, da restaurao da view invocao da aplicao; Lifecycle.render(javax.faces.context.FacesContext): cuida da fase de renderizao de respostas que devero ser enviadas ao cliente (normalmente, um navegador web);

Figura 1. Ciclo de vida de requisies JSF. Observe que apenas a renderizao separada dos demais blocos do ciclo de vida, fato justificado pela maior complexidade associada a esta fase. Nos dois mtodos listados, vemos que h um parmetro de entrada que guarda uma instncia de contexto, criada para o tratamento da requisio. Este objeto ser, passo a passo, recheado com todas as informaes pertinentes interao atual, de modo a representar de forma fiel a situao da aplicao, a cada momento. A primeira fase do ciclo de vida a Restaurao de uma view, que, em JSF, representada genericamente pela classe javax.faces.view.ViewDeclarationLanguage. Nesta fase, o controlador procurar por uma view cujo identificador (view ID) corresponda exatamente quele passado na requisio. Caso no a encontre, ela precisar ser totalmente montada. Por outro lado, se for encontrada, ser apenas restaurada. Em ambos os casos, o objetivo desta fase fazer com que a view associada requisio esteja devidamente montada e identificada no lado servidor. A forma que o JSF usa para manter esta representao de uma view em memria a de uma rvore de objetos, que se inicia a partir de uma raiz (uma instncia de javax.faces.component.UIViewRoot), na qual todos os demais elementos (especializaes de javax.faces.component.UIComponent) esto vinculados. As quatro fases seguintes do ciclo de vida, descritas abaixo, sero executadas apenas nos casos em que a requisio tenha dados a serem processados. Caso contrrio, sero ignoradas e apenas a etapa de Renderizao de resposta ser efetivamente processada. Um bom exemplo de cenrio em que a resposta imediatamente renderizada depois da execuo da restaurao da view aquele em que o usurio acessa o sistema pela primeira vez e a tela inicial deve ser exibida. Neste caso, no h nenhum dado sensvel vindo do cliente e nenhuma ao disparada pelo mesmo; o que existe apenas uma solicitao de inicializao do sistema e nada mais. A segunda etapa no ciclo de vida JSF a Aplicao dos valores da request. Nela, cada componente da rvore citada anteriormente ter uma chance de avaliar os parmetros enviados pelo cliente na requisio, identificar quais se relacionam com ele e, por fim, atualizar-se de modo a refletir exatamente o estado atual da aplicao, guardando todos esses valores localmente. Ento, a mquina de estados movida para a fase do Processamento de validaes. Novamente, dada uma chance, para cada componente da view, de executar todas as converses e validaes a eles associadas. Este o momento em que a checagem de intervalos de dados e/ou converses de tipos so realizadas, de

modo a assegurar que os dados preenchidos no cliente sejam vlidos e representem exatamente o que devem representar. Se todos os valores preenchidos no cliente forem vlidos e todas as converses programadas forem bem sucedidas, ser permitido que a fase de Atualizao dos valores de modelo seja executada. At o momento anterior, o foco estava todo na camada de apresentao, em que cada componente da view guardava localmente os dados a ele associados. Neste instante, entretanto, j seguro refletir na camada de modelo todas as informaes contidas na camada de apresentao. Para isso, faz-se uso de beans gerenciados (ou backing beans), associados s views por meio da Linguagem de Expresso (EL, definida na JSR-341), especificao que tambm compe a Java EE e da qual o JSF faz uso massivo. At aqui, todos os dados preenchidos e selecionados na view j esto devidamente referenciados na camada de modelo. A prxima fase, de Invocao da aplicao, consiste em dar aos componentes da view a chance de executarem aes disparadas pelo cliente. Apenas para facilitar a visualizao, imagine uma ao como sendo um clique em um boto de submisso de formulrio. Novamente, h aqui a possibilidade de um bean gerenciado estar envolvido no processo, desde que mtodos implementados por ele sejam vinculados a propriedades de ao dos componentes desta view, tambm por meio da j citada EL. nesta fase que, atravs de regras de navegao mapeadas no sistema (mais especificamente, no arquivo de configuraes JSF, o popular faces-config.xml), define-se a prxima view a ser apresentada para o cliente, atravs da configurao e utilizao de outcomes. A ltima fase do ciclo de vida JSF a Renderizao da resposta. Aqui, o sistema j conhece a view que deve ser apresentada ao cliente, bem como todos os dados que devem ser vinculados a ela. Logo, necessrio que cada objeto da rvore de componentes JSF seja devidamente convertido para uma linguagem que seja legvel para o cliente. Embora JSF possa ser estendido para trabalhar com outras linguagens de marcao e outros protocolos, toda a sua implementao padro est baseada em HTTP(s) e HTML. Quando o processo de traduo finalizado, o objeto de resposta preparado e, por fim, enviado para o cliente atravs do mesmo controlador frontal, FacesServlet, j mencionado no incio do ciclo de vida. Ao final da etapa de Renderizao da resposta, o contedo criado finalmente enviado ao cliente, atravs do objeto de resposta (ServletResponse) gerado e manipulado diretamente pelo controlador frontal do framework (FacesServlet). Este , portanto, o processo completo de tratamento de requisies de usurio. Mas, afinal, onde (e de que maneira) se encaixa a Big Ticket feature intitulada HTML Friendly Markups? O fato que, desde a JSF 2.0, a linguagem padro para declarao de views (View Declaration Language, ou VDL) a Facelets, substituta direta da velha conhecida tecnologia de todo programador web em Java, o JSP (JavaServer Pages). Cada marcador escrito nesta VDL est associado a um componente do framework (que ser, por sua vez, uma especializao de javax.faces.component.UIComponent), e os processos de encoding (traduo de HTML para componentes Java) e decoding (traduo de componentes Java para cdigo HTML) que ocorrem nas fases de Restaurao de views e Renderizao de respostas so realizados por agentes conhecidos, respectivamente, como view handlers (no caso do encoding em nvel de views), tag handlers (no caso de encoding em nvel de marcadores) e renderizadores. Todos eles so acionados a partir da instncia de javax.faces.view.ViewDeclarationLanguage que representa a view em questo, como j dito. Pginas construdas com o uso de Facelets acabam obrigatoriamente vinculadas ao processo de renderizao do JSF. Sendo assim, para que se tenha uma ideia de como ela ser exibida ao usurio final, necessrio que implantemos esse sistema em um servidor de aplicaes (como GlassFish, WebSphere ou JBoss) ou um servidor web (como Jetty ou Tomcat) e o coloquemos em execuo. Esta nova caracterstica trazida pelo JSF 2.2, no entanto, apresenta dois aspectos que nos permitem mudar significativamente a forma de trabalhar a interface com o usurio: os atributos e os elementos passthrough. Como os prprios nomes sugerem, esses elementos so ignorados pelo processo convencional do JSF para a interpretao dos elementos de uma view, uma vez que eles no tm participao na fase de

renderizao e sero teis apenas no processamento de contedo, no ambiente servidor. Veremos, a seguir, como cada um funciona. Atributos pass-through Todo marcador JSF possui um conjunto de atributos composto por uma combinao de propriedades definidas no componente (javax.faces.component.UIComponent) e no renderizador (especializao de javax.faces.render.Renderer) para ele projetados. Conforme j vimos no ciclo de vida acima, cada elemento da view tem a chance de ler e processar parmetros escritos na requisio que chega ao servidor. Para facilitar a visualizao disso, basta que imaginemos um elemento muito comum em pginas web: uma caixa de texto. Enquanto uma palavra digitada uma propriedade do componente (com valor de negcio, muitas vezes, sendo usada para atualizao do modelo em fases mais avanadas do ciclo de vida), seu tamanho em pixels algo mais relacionado forma como ela dever ser desenhada para o usurio. Em ambos os casos, tanto o renderizador quanto o componente j sabem, de antemo, exatamente quais os dados que devem procurar em cada requisio que chega, pois se trata de algo que pertence ao projeto dessas classes. No entanto, atributos pass-through tm um propsito diferente: permitir ao programador que defina atributos adicionais, arbitrrios ou no, que sero ignorados tanto pelo componente quanto pelo renderizador a ele associado. Para exemplificar, vejamos o cdigo da Listagem 1. Nela, vemos as trs formas possveis de se trabalhar com atributos desta natureza, que so: 1. Por meio do emprego do marcador f:passThroughAttribute, definindo-se a chave (name) e o valor (value) do atributo. Esta abordagem foi usada no componente de identificador passthrough; 2. Por meio do marcador f:passThroughAttributes, definindo-se um mapa de valores (que ser uma implementao de java.util.Map<String, Object>) que ser associado a um conjunto de atributos. Esta abordagem foi usada no componente de identificador passthrough2; 3. Por meio do uso de atributos inseridos no prprio marcador que representa o elemento HTML, seguindo um espao de nomes especfico para atributos pass-through (http://xmlns.jcp.org/jsf/passthrough) declarado e prefixado (neste caso, com pt, de pass-through) na view em questo (<html>). Esta abordagem foi usada no componente de identificador passthrough3. Perceba que, neste caso usamos tanto um atributo com semntica previamente conhecida (placeholder, que define um texto de apoio/sugesto ao usurio, popularmente conhecido como hint text) quanto outro absolutamente arbitrrio (chaveQualquer), ao qual no h semntica alguma previamente associada. Listagem 1. Pgina home.xhtml, que trabalha com atributos pass-through aplicados a facelets.

<?xml version="1.0" encoding="UTF-8"?> <!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:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"> <h:head> <title>Java Server Faces 2.2 - Java Magazine</title> </h:head> <h:body>

<div align="center" > <h:form prependId="false"> <h:outputText value="Testando pass-through individual:" /> <h:inputText value="#{htmlFriendlyMB.passThroughAttribute}" id="passthrough" binding= "#{htmlFriendlyMB.campoTexto}" > <f:passThroughAttribute name="passthroughAttr1" value="Testando passthrough" /> </h:inputText> <br/><br/> <h:outputText value="Testando pass-through via mapa:" /> <h:inputText value="#{htmlFriendlyMB.passThroughAttribute}" id="passthrough2" binding= "#{htmlFriendlyMB.campoTexto2}" > <f:passThroughAttributes value="#{htmlFriendlyMB.passThroughAttributeMap}" /> </h:inputText> <br/><br/> <h:outputText value="Testando pass-through via namespace:" /> <h:inputText value="#{htmlFriendlyMB.passThroughAttribute}" pt:placeholder="Entre com o valor" id="passthrough3" pt:chaveQualquer="Valor arbitrrio" binding="#{htmlFriendlyMB.campoTexto3}"/> <br/><br/> <h:commandButton id="cmdPassThrough" value="Analisar" action="#{htmlFriendlyMB.processarAtributosPassThrough()}" /> </h:form> </div> </h:body> </html>

A recuperao dos valores pass-through associados a elementos HTML, no lado servidor, possvel a partir de uma nova API incorporada classe javax.faces.component.UIComponent, assim definida: 1. getPassThroughAttributes(boolean criarMapa): java.util.Map<String, Object> este mtodo tem como parmetro uma varivel booleana que, ao ser valorada com true, estabelece que um novo mapa de objetos deva ser criado caso ainda no exista um mapa de atributos pass-through vinculado ao componente. Quando este parmetro for false, no entanto, estabelece-se que null ser retornado caso este componente no tenha um mapa de atributos pass-through associado a ele no instante em que o mtodo for invocado; 2. getPassThroughAttributes(): java.util.Map<String, Object> este mtodo uma simplificao do anterior. Na prtica, a sua execuo consiste em uma chamada a getPassThroughAttributes(boolean) passando true como valor de entrada. Usando-se este mtodo, portanto, um ponteiro nulo jamais ser devolvido a quem o invocou; Observe a Listagem 2, na qual temos um bean gerenciado fazendo uso dos mtodos recm-listados. Cada componente usado na construo da rvore que representa a view da Listagem 1 possui um mapa prprio de atributos pass-through, e cada um dos valores pode ser facilmente recuperado atravs da chave que o identifica nesta coleo. Para facilitar a demonstrao prtica disto, fizemos uso do atributo binding nos

elementos da Listagem 1 para associ-los a instncias de componentes definidas programaticamente no bean gerenciado da Listagem 2, a partir dos atributos nomeados como campoTexto, campoTexto2 e campoTexto3. Alm dos campos de texto citados acima, a view da Listagem 1 tambm contm um boto, identificado como cmdPassThrough. Quando ele clicado, dispara uma chamada ao mtodo de assinatura processarAtributosPassThrough(), implementado pela classe HtmlFriendlyMB. Este mtodo, uma vez chamado, dispara uma chamada a trs outros mtodos privados, em sequncia, assim definidos: 1. analisarAtributoPassThrough():void percorre o mapa de atributos do componente identificado pelo ID passthrough e imprime o valor de cada atributo na console; 2. percorrerMapaDeAtributos():void percorre o mapa de atributos do componente identificado pelo ID passthrough2 e imprime seus valores na console; 3. analisarPassthroughViaNamespace():void percorre o mapa de atributos do componente identificado pelo ID passthrough3 e imprime o valor de cada atributo na console. Listagem 2. HtmlFriendlyMB.java: bean gerenciado que trata do processamento de atributos pass-through.
package br.com.devmedia.jsf22.controller; import java.util.HashMap; import java.util.Map; import javax.inject.Named; import javax.enterprise.context.RequestScoped; import javax.faces.component.UIComponent; /** * Bean gerenciado usado para mostrar os recursos da caracterstica de * marcadores amigveis ao HTML 5 do JSF 2.2. * * @author pedrobrigatto */ @Named(value = "htmlFriendlyMB") @RequestScoped public class HtmlFriendlyMB { private String passThroughAttribute; private Map<String, Object> passThroughAttributeMap; private UIComponent campoTexto; private UIComponent campoTexto2; private UIComponent campoTexto3; private int contador = 0; public HtmlFriendlyMB() { this.passThroughAttributeMap = new HashMap<>(); this.passThroughAttributeMap.put("Atributo1", "Testando"); this.passThroughAttributeMap.put("Atributo2", "Atributos");

this.passThroughAttributeMap.put("Atributo3", "Pass-through"); } //... getters e setters para todos os atributos do bean gerenciado public void processar() { resultado = String.format("Este texto j foi modificado %d vezes", ++contador); System.out.println(resultado); } /** * Mtodo usado para processar atributos pass-through, recurso disponibilizado * na verso 2.2. da especificao JSF. */ public void processarAtributosPassThrough() { analisarAtributoPassThrough(); percorrerMapaDeAtributos(); analisarPassthroughViaNamespace(); } private void analisarAtributoPassThrough() { if (campoTexto != null) { System.out.println(String.format( "@@@@@ O atributo foi recuperado e tem valor %s", campoTexto.getPassThroughAttributes() .get("passthroughAttr1"). toString())); } } private void percorrerMapaDeAtributos() { if (campoTexto2 != null) { System.out.println(String.format( "##### O ID do campo utilizando mapa de atributos pass-through %s", campoTexto.getId())); Map<String, Object> mapa = campoTexto2 .getPassThroughAttributes(); for (Map.Entry item : mapa.entrySet()) { System.out.println(String.format( ">>>>> Atributo pass-through detectado com chave %s e valor %s", item.getKey().

toString(), item.getValue().toString())); } } } private void analisarPassthroughViaNamespace() { if (campoTexto3 != null) { Map<String, Object> mapa = campoTexto3. getPassThroughAttributes(); for (Map.Entry item : mapa.entrySet()) { System.out.println(String.format( ">>>>> Atributo pass-through detectado com chave %s e valor %s", item.getKey().toString(), item.getValue().toString())); } } } public Map<String, Object> getPassThroughAttributeMap() { return passThroughAttributeMap; } public void setPassThroughAttributeMap (Map<String, Object> passThroughAttributeMap) { this.passThroughAttributeMap = passThroughAttributeMap; } }

Por fim, na Listagem 3, apresentamos o texto impresso como resultado da execuo do cdigo acima descrito. Ali, podemos ver que, de fato, todos os atributos associados aos Facelets usados na construo da view da Listagem 1 foram recuperados e analisados com sucesso. Atributos pass-through, como vimos, podem ser arbitrrios, isto , identificados livremente de acordo com os planos da equipe de desenvolvimento de projetos em Java para a web. Dessa forma, podemos rechear componentes de uma view com um conjunto varivel de informaes adicionais e que podem influenciar, no ambiente servidor, tanto no modelo de dados quanto no prprio visual da pgina atual ou de uma pgina seguinte do fluxo em questo. Caber, portanto, ao programador decidir se o conjunto de atributos da prpria API de componentes JSF suficiente para guardar todas as informaes de uma view ou se o uso de um conjunto adicional de dados, identificados arbitrariamente, pode ser interessante. Em qualquer um dos casos, o fato importante a ser registrado aqui que, agora, isto no apenas possvel, mas extremamente simples de se fazer em JSF. Vejamos agora como funciona o conceito de elementos pass-through. Listagem 3. Log do servidor contendo os valores dos atributos pass-through recuperados em tempo de execuo.

INFO: INFO: INFO: INFO: INFO: INFO: INFO: INFO:

JM-JSF22-1 foi implantado com sucesso em 6,738 milissegundos. @@@@@ O atributo foi recuperado e tem valor Testando passthrough ##### O ID do campo utilizando mapa de atributos pass-through ? passthrough >>>>> Atributo pass-through detectado com chave Atributo2 e valor Atributos >>>>> Atributo pass-through detectado com chave Atributo1 e valor Testando >>>>> Atributo pass-through detectado com chave Atributo3 e valor Pass-through >>>>> Atributo pass-through detectado com chave chaveQualquer e valor Valor arbitrrio >>>>> Atributo pass-through detectado com chave placeholder e valor Entre com o valor

Elementos pass-through Esta abordagem traz ainda mais liberdade ao autor de pginas em sistemas web desenvolvidos sobre a plataforma Java EE. Enquanto, com atributos pass-through, falamos exclusivamente de campos associados a componentes de uma view (escritos a partir da VDL Facelets), agora trataremos de elementos de uma view declarados a partir de HTML puro e que, por serem assim declarados, passam sobre o mecanismo convencional de renderizao do JSF. A grande marca desta estratgia est no fato de que, muito embora o contedo de uma view possa ser construdo a partir de elementos escritos em HTML, no h prejuzo algum para o sistema em si no tocante a todos os recursos que o JSF prov no ambiente servidor. A mgica, neste caso, fica por conta de uma pea central de decorao de contedo, responsvel pelo mapeamento de elementos HTML para elementos JSF. A API responsvel por este processo est contida na classe javax.faces.view.facelets.TagDecorator, sensivelmente aprimorada nesta nova verso da especificao. Este decorador colocado para trabalhar em uma fase do ciclo de vida conhecida como Restaurao da view, abordada h pouco. Nesta fase, a instncia de javax.faces.view.ViewDeclarationLanguage que representa a view atual passa por sua criao ou restaurao. O mtodo no qual este processo de restaurao ocorre pertence API de ViewDeclarationLanguage e tem a seguinte assinatura: buildView(FacesContext, UIViewRoot) Este mtodo invocado a partir do j descrito controlador frontal da especificao JSF, FacesServlet, nos momentos iniciais do tratamento da requisio de usurio. O fluxo completo denso, mas pode ser resumido pelo diagrama da Figura 2. Por ela, vemos que o decorador atua como um agente do framework que, analisando cada marcador definido na view em questo, buscar em uma tabela o seu elemento JSF correspondente. Caso no o encontre, atribuir a ele um mapeamento genrico, como veremos mais adiante no texto. Desta forma, ainda que o programador/designer crie uma view fazendo uso apenas de HTML, servios do framework faro com que ela tenha sua representao no lado servidor, tal como acontece com views desenhadas a partir de Facelets.

Figura 2. Representao do processo de decorao de marcadores. Mas, afinal de contas, de onde vm os dados para que o mapeamento citado ocorra? Quais so os critrios e as informaes que o decorador utilizar para que este processo se conclua com sucesso? A resposta est na Tabela 2. Este o conjunto de dados no qual o decorador se baseia para, marcador a marcador definido na view, encontrar o seu elemento JSF correspondente. Perceba que, para uma grande gama de marcadores HTML, h um conjunto de combinaes possveis que culminam na definio do marcador alvo na biblioteca JSF. Para os casos em que no h uma regra de mapeamento especfica, a documentao estabelece que ele seja associado ao elemento genrico elemento. Uma vez que o contedo a ser renderizado HTML puro, no existe a necessidade de se mapear todos os elementos HTML a componentes especficos da biblioteca do JSF; entretanto, algumas associaes so essenciais, como, por exemplo, o bloco lgico a ser executado no clique de um boto de uma pgina. A grande vantagem do uso de elementos pass-through a possibilidade de, a partir deles, desenharmos pginas web somente com a linguagem HTML, ignorando o processo de renderizao do JSF sem perder, com isso, todos os demais recursos do framework no tratamento de views do lado servidor. Para entendermos melhor como tudo isso funciona, vejamos o contedo da Listagem 4. Listagem 4. Index.xhtml pgina que faz uso de elementos pass-through.
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:jsf="http://xmlns.jcp.org/jsf" xmlns:f="http://java.sun.com/jsf/core"> <head jsf:id="head"> <title>Putting it all together </title> </head> <body jsf:id="body"> <form jsf:id="form" jsf:prependId="false"> <label jsf:for="name">Name </label> <input jsf:id="name" type="text" jsf:value="#{htmlFriendlyMB2.name}" /> <label jsf:for="tel">Tel </label>

<input jsf:id="tel" type="text" jsf:value="#{htmlFriendlyMB2.tel}" /> <label jsf:for="email">Email </label> <input jsf:id="email" type="text" jsf:value="#{htmlFriendlyMB2.email}" /> <input type="submit" value="Executar" jsf:id="acao" jsf:action="#{htmlFriendlyMB2.processar}" > <f:ajax execute="@form" render="name tel email" event="action" /> </input> </form> </body> </html>

Tabela 2. Base para decorao de elementos HTML. Nela, todos os elementos da view foram escritos em HTML 5. No h, como na Listagem 1, o uso de Facelets para a composio da estrutura da pgina. Ou seja: h, aqui, uma clara independncia em relao aos elementos JSF para a definio da interface com o usurio, deixando o programador ou designer web absolutamente livre para trabalhar todos os seus conceitos de experincia de usurio de forma bem mais ampla. Alm disso, toda pgina desenvolvida apenas com elementos HTML pode ser facilmente aberta e visualizada em qualquer navegador web sem a necessidade de submet-la ao runtime JSF. No entanto, devido ao j mencionado processo de decorao encapsulado pela classe TagDecorator, nenhum dos recursos JSF perdido pelo desenvolvedor no ambiente servidor. O mapeamento apresentado pela Tabela 2,

bem como todas as regras estabelecidas para a associao entre elementos HTML, view handlers, tag handlers e renderizadores, garante que a rvore de componentes seja criada, mantida e represente, deste modo, os estados de cada elemento da view em questo. Logo, o que temos no ambiente servidor ainda so objetos JSF, o que nos permite trabalhar novamente com o conceito de valores pass-through atravs da mesma API j citada. Perceba que a view da Listagem 4 comea declarando o espao de nomes http://xmlns.jcp.org/jsf, identificado pelo prefixo jsf, no qual esto definidos atributos a serem usados ao longo de sua estrutura. Todas as caixas de entrada de texto utilizadas trabalham com um dos atributos definidos neste espao de nomes, (jsf:id), para assim serem identificadas unicamente no documento. Alm disso, trabalham tambm com o atributo (jsf:value) para vincular os dados nelas preenchidas a atributos definidos em um bean gerenciado, que veremos em instantes. O ltimo elemento definido dentro do formulrio um boto de submisso, e aqui mais um atributo deste espao de nomes utilizado (jsf:action) para vincular eventos de ao disparados por ele a um mtodo do mesmo bean gerenciado que descreveremos logo mais. At aqui, vimos como a view HTML foi montada. Conforme dito acima, todos os campos dela foram vinculados a atributos e mtodos de um bean gerenciado. Este bean gerenciado, apresentado na Listagem 5, est implementado em uma classe de nome HtmlFriendlyMB2, configurada para estar acessvel via EL atravs do identificador htmlFriendlyMB2 e cujo escopo ser de sesso. Os campos da pgina tm seus valores vinculados, cada qual, a um atributo do tipo java.lang.String deste bean, e o boto de submisso de formulrio est configurado para disparar (na fase de Invocao da Aplicao do ciclo de vida, como j vimos) um mtodo cuja assinatura a seguinte: processar (): void e que, no exemplo, apenas imprime o nmero de vezes em que o formulrio foi submetido; valor este que fica guardado em um contador que incrementado a cada clique do boto. A Listagem 6 apresenta o log do servidor quando este sistema colocado novamente para executar. Como podemos notar, uma pgina cujos elementos de interface esto todos escritos em HTML 5, fazendo uso de atributos personalizados e descritos em um novo espao de nomes da especificao JSF, consegue se comunicar com um bean gerenciado Java, em um ambiente JSF, da mesma forma que j estamos acostumados a ver quando usamos Facelets ou JSF como VDL para a construo das views de nossos sistemas. Listagem 5. HtmlFriendlyMB2.java: bean gerenciado que exemplifica o uso de elementos pass-through
package br.com.devmedia.jsf22.controller; import java.io.Serializable; import javax.enterprise.context.SessionScoped; import javax.inject.Named; /** * Bean gerenciado de escopo de sesso para exemplificar o uso de elementos pass-through * da especificao JSF 2.2. * * @author pedrobrigatto */ @Named(value = "htmlFriendlyMB2") @SessionScoped public class HtmlFriendlyMB2 implements Serializable {

private String name; private String tel; private String email; private String resultado; private int contador = 0; public HtmlFriendlyMB2() {} //... getters e setters para todos os atributos da classe public void processar() { resultado = String.format("Este texto j foi modificado %d vezes", ++contador); System.out.println(resultado); } }

Listagem 6. Log da aplicao exemplificando o uso de elementos pass-through


INFO: Inicializando Mojarra 2.2.0 ( 20130502-2118 https://svn.java.net/svn/mojarra~svn/tags/2.2.0@11930) para o contexto '/JM-JSF22-1' INFO: INFO: INFO: INFO: INFO: INFO: Monitoring jndi:/server/JM-JSF22-1/WEB-INF/ faces-config.xml for modifications Loading application [JM-JSF22-1] at [/JM-JSF22-1] JM-JSF22-1 foi implantado com sucesso em 3,004 milissegundos. Este texto j? foi modificado 1 vezes Este texto j? foi modificado 2 vezes Este texto j? foi modificado 3 vezes

Isto tudo o que precisamos saber, de incio, a respeito do recurso de marcadores amigveis HTML 5. Com tudo o que foi apresentado at aqui, o leitor j ser capaz de fazer algumas experincias bem interessantes e testar, por si mesmo, todos os benefcios trazidos a partir desta Big Ticket Feature. Vejamos, a partir de agora, outra caracterstica central do JSF 2.2: Faces Flow. Faces Flow Outra novidade trazida pelo JSF 2.2 o suporte ao desenvolvimento de sistemas web orientados a fluxos (workflows). Esta caracterstica, intitulada Faces Flow, foi elaborada em cima dos melhores recursos existentes em outros frameworks tambm orientados a fluxos e j consolidados no mercado. So eles: Apache MyFaces CODI; Oracle ADF Task Flow; Spring Web Flow. A partir de agora, ser possvel encapsular um conjunto de views/pginas em um pacote independente de todos os demais, totalmente reutilizvel e que, sozinho, ser capaz de representar uma funcionalidade do

sistema. Desta maneira, as aplicaes deixam de ter um nico e grande fluxo, e essas pequenas unidades passam a ser combinadas para compor uma soluo final. At a plataforma Java EE 6, o escopo que mais chegava prximo ao de um fluxo era o de conversao (javax.enterprise.context.ConversationScoped), introduzido com a especificao CDI (Contexts and Dependency Injection) em sua verso 1.0. No entanto, este escopo um pouco mais amplo que o de um workflow, pois uma conversa entre cliente e servidor pode ser composta por um conjunto varivel de fluxos. Para simplificar a visualizao, uma conversao pode ser interpretada como uma aba de um navegador web executando uma aplicao qualquer. Quando, por uma necessidade qualquer, o mesmo usurio abre, em duas abas distintas, a mesma aplicao (ainda que em funes diferentes), ter sua disposio duas conversaes independentes entre si, mas que compartilham da mesma sesso de usurio. Fluxos, no entanto, algo diferente. So definidos por um ponto nico de entrada, outro tambm nico de sada e um conjunto varivel de passos intermedirios. Tambm podem envolver parmetros de entrada e de sada, usados para receber valores de alguns fluxos e enviar valores para outros. Pontos de entrada, pontos de sada e todos os outros elementos de um fluxo so conhecidos, na literatura, como ns, e esta a nomenclatura que usaremos no texto que se segue. Para facilitar o entendimento, imagine um cadastro em sites de emprego, em que trs etapas devem ser cumpridas para que uma candidatura seja efetuada. Este processo est ilustrado na Figura 3. Em um primeiro momento, preenchem-se os dados gerais do candidato (como nome, e-mail e telefones de contato). Feito isso, a prxima etapa apresentada, em que informaes sobre escolaridade devem ser fornecidas. A terceira e ltima etapa consiste na digitao de dados referentes ao histrico profissional da pessoa. Somente quando todos esses dados so passados para o sistema que o cadastramento desta pessoa poder, finalmente, ser realizado. Este um caso clssico de fluxo, e o leque de cenrios similares a ele ilustra muito bem o quanto importante, para uma especificao como a JavaServer Faces, ter em seu arsenal um recurso nativo para a implementao de casos desta natureza.

Figura 3. Um modelo de tela para ilustrar o conceito de workflow. Outro cenrio to ou mais comum quanto o exposto acima o de venda de produtos pela Internet, em que passos como Identificao do usurio, Preenchimento de dados de pagamento (carto de crdito, data de validade, parcelamento, bandeira, dentre outros) e Finalizao da compra so, todos eles, necessrios para que, enfim, seja realizado o processamento da transao. Este outro cenrio que ajuda a esclarecer ao leitor o conceito de um workflow de forma bem prtica.

Este ltimo caso mencionado nos ajuda muito a entender, inclusive, a questo do reuso de fluxos. Imagine que, em sua empresa, seja necessrio desenvolver um mdulo de pagamento online para um site de comrcio eletrnico de um de seus clientes. No difcil imaginar que ele poder ser til, tambm, em projetos similares, com escopos semelhantes. Por isso, seria extremamente interessante desenvolv-lo como um mdulo, independente de um sistema especfico, para poder lig-lo em qualquer soluo em que fosse interessante. Reuso, portanto, indubitavelmente o maior valor agregado por esta caracterstica para o JSF. Como citado anteriormente, Faces Flow muda o foco de pginas para ns. De acordo com a especificao, so cinco os tipos possveis de ns: 1. View: um pedao de uma pgina ou uma pgina completa; 2. Chamada a mtodo: invocao de mtodos via Expression Language; 3. Switch: deciso de navegao baseada em condies booleanas; 4. Chamada a fluxo: consiste em uma chamada de um fluxo a outro; 5. Retorno de fluxo: consiste em uma configurao de sada de um fluxo. Faces Flow demandou, ainda, a criao de duas novas anotaes (CDI), sendo elas: @javax.faces.flow.FlowScoped: que associa o tempo de vida de beans gerenciados assim anotados ao tempo de durao de um dado fluxo; @javax.faces.flow.builder.FlowDefinition: usada para configurar mtodos de uma classe que tm por objetivo construir, programaticamente, um fluxo dentro de uma aplicao. A especificao tambm define um novo objeto acessvel via EL, identificado pelo nome flowScope. Para acess-lo dentro de uma view, por exemplo, basta que utilizemos a notao #{flowScope}, exatamente como j fazemos com beans gerenciados e outros objetos JSF pr-configurados, como application. Quando este objeto de escopo acessado via EL em views, o que ocorre nos bastidores uma chamada ao mtodo facesContext.getApplication().getFlowHandler().getCurrentFlowScope(). dentro deste objeto de escopo que, por exemplo, sero guardados parmetros que devem ser passados de um fluxo para outro, conforme veremos daqui a instantes. H uma srie de outros detalhes aos quais devemos nos atentar. Para no tornar a anlise maante, no entanto, faremos uso de um exemplo contido no tutorial da especificao Java EE, que tem como tema a realizao de checkouts em uma loja online, hipottica. Este exemplo pode ser baixado atravs de uma ferramenta do GlassFish chamada Update Tool, e as instrues de como faz-lo esto na seo Links no final do artigo. Comearemos pela ilustrao da Figura 4, que apresenta a comunicao entre os fluxos propostos no projeto mencionado.

Figura 4. Representao dos fluxos da aplicao de checkout. Pelo diagrama, vemos dois fluxos implementados. O primeiro deles, chamado joinFlow, foi configurado declarativamente (ou seja, atravs de um arquivo XML, chamado joinFlow-flow.xml) e contm apenas dois ns, identificados por joinFlow.xhtml e joinFlow2.xhtml. O segundo, chamado checkoutFlow, foi configurado atravs da API de Faces Flow e constitudo de quatro ns, identificados pelos nomes checkoutFlow.xhtml, checkoutFlow2.xhtml, checkoutFlow3.xhtml e checkoutFlow4.xhtml. Ambos os fluxos utilizam beans gerenciados para guardar valores de entrada e processar aes das views neles contidas. Passaremos, agora, anlise do primeiro fluxo citado, joinFlow. Observe a Listagem 7, na qual apresentado o arquivo XML usado para configur-lo. A definio do fluxo, representada pelo marcador <flow-definition>, tem um atributo denominado id usado para estabelecer o seu identificador nico em toda a aplicao. Logo em seguida, um n de retorno configurado, de modo que seu valor seja recuperado, dinamicamente, atravs de um atributo de um bean gerenciado, o qual veremos em detalhes mais adiante. Parmetros de entrada tambm so definidos (param1CheckoutFlow e param2CheckoutFlow), os quais sero usados para a transmisso de valores iniciais de checkoutFlow para joinFlow. Por fim, um n de chamada de fluxo configurado para estabelecer o modo pelo qual joinFlow invocar checkoutFlow, que exatamente a comunicao entre fluxos ilustrada na Figura 4. Perceba que, para esta chamada, dois parmetros de sada so definidos (param1FromJoinFlow e param2FromJoinFlow), sobre os quais voltaremos a falar logo mais. A conveno de Faces Flow determina que o n de entrada de todo fluxo aquele que recebe exatamente o mesmo nome do fluxo propriamente dito. Este o caso de joinFlow.xhtml, apresentado na Listagem 8. Este um cdigo particularmente rico, atravs do qual conseguiremos visualizar boa parte dos elementos citados at aqui. Listagem 7. joinFlow-flow.xml. Configurao do fluxo joinFlow de forma declarativa (XML).
<?xml version='1.0' encoding='UTF-8'?> <!-Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. You may not modify, use, reproduce, or distribute this software except in compliance with --> <faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee" the terms of the License at: http://java.net/projects/javaeetutorial/pages/BerkeleyLicense

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"> <flow-definition id="joinFlow"> <flow-return id="returnFromJoinFlow"> <from-outcome>#{joinFlowBean.returnValue}</from-outcome> </flow-return> <inbound-parameter> <name>param1FromCheckoutFlow</name> <value>#{flowScope.param1Value}</value> </inbound-parameter> <inbound-parameter> <name>param2FromCheckoutFlow</name> <value>#{flowScope.param2Value}</value> </inbound-parameter> <flow-call id="callcheckoutFlow"> <flow-reference> <flow-id>checkoutFlow</flow-id> </flow-reference> <outbound-parameter> <name>param1FromJoinFlow</name> <value>param1 joinFlow value</value> </outbound-parameter> <outbound-parameter> <name>param2FromJoinFlow</name> <value>param2 joinFlow value</value> </outbound-parameter> </flow-call> </flow-definition> </faces-config>

Listagem 8. joinFlow.xhtml. Ponto de entrada do fluxo identificado como joinFlow.


<?xml version='1.0' encoding='UTF-8' ?> <!-Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. You may not modify, use, reproduce, or distribute this software except in compliance with --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> the terms of the License at: http://java.net/projects/javaeetutorial/pages/BerkeleyLicense

<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <h:outputStylesheet library="css" name="stylesheet.css"/> <title>Join Flow Page One</title> </h:head> <h:body style="background-color: lightgoldenrodyellow"> <h:form prependId="false"> <h:graphicImage url="#{resource['images:duke.books.gif']}" alt="Duke carrying books"/> <h2>Join Flow Page One</h2> <p>Thank you, <span id="param1FromCheckoutFlow"> #{flowScope.param1Value}</span> from <span id="param2FromCheckoutFlow"> #{flowScope.param2Value}</span>. (Reading the parameters passed in from the checkout flow, if there are any.)</p> <p>Check the boxes to receive our newsletters or special offers.</p> <h:panelGrid columns="2" role="presentation"> <h:outputLabel for="clubcheck" value="Yes! I'd like to join the Duke Fan Club!"/> <h:selectBooleanCheckbox id="clubcheck" value="#{joinFlowBean.fanClub}"/> <h:outputLabel for="newslettercheckbox" value="Send me these FREE newsletters:"/> <h:selectManyCheckbox id="newslettercheckbox" layout="pageDirection" value="#{joinFlowBean.newsletters}"> <f:selectItems value="#{joinFlowBean.newsletterItems}"/> </h:selectManyCheckbox> </h:panelGrid> <p>Click Submit to continue, or Home to go to the site home page.</p> <p><h:commandButton value="Submit" action="joinFlow2"/></p> <p><h:commandButton value="Exit Flow" action="returnFromJoinFlow"/></p> </h:form> </h:body> </html>

O primeiro desses elementos e sobre o qual falaremos o parmetro de entrada, que pode ser usado para passar valores de um fluxo a outro. Todo parmetro, como j mencionamos, guardado no escopo de fluxo, e de l recuperado quando for preciso. Na view de entrada de joinFlow, apresentado na Listagem 7, h dois desses campos posicionados logo no incio do cdigo. Perceba que, identificados pelos nomes param1FromCheckoutFlow e param2FromCheckoutFlow, eles usam exatamente o objeto de escopo para recuperar seus valores, que estaro guardados, respectivamente, nos atributos param1Value e param2Value de flowScope. Outro ponto tambm destacado no cdigo desta view a configurao de um n de retorno, mapeado em um de seus botes de comando. Perceba que o identificador do valor de retorno exatamente aquele usado na Listagem 7, sendo suficiente para que a navegao seja realizada corretamente. Alm deste boto, temos outro que apenas aponta para o prximo passo de joinFlow. O bean gerenciado responsvel pelo tratamento de joinFlow pode ser analisado na Listagem 9. No tomaremos muito tempo com este cdigo, pois a nica novidade em relao ao que j conhecemos sobre JSF o uso do novo escopo do CDI, FlowScoped, que garante que o tempo de vida de objetos desta classe seja exatamente o tempo de vida do fluxo ao qual eles sejam associados. Ao utilizarmos este tipo de escopo em beans gerenciados, devemos apenas nos preocupar em garantir que o ID do fluxo associado ao escopo seja exatamente aquele do fluxo ao qual desejamos vincular esta classe. Fechando a anlise deste primeiro fluxo, temos a Listagem 10, com o contedo de seu segundo e definitivo passo. O ponto que merece destaque, aqui, a referncia ao segundo fluxo da aplicao, checkoutFlow. Isto feito configurando-se um dos botes da view para disparar a execuo do n de chamada de fluxo configurado em joinFlow, o qual, por sua vez, j se encontra configurado para encontrar e iniciar o fluxo de checkout, como j tivemos a oportunidade de ver na Listagem 7. Listagem 9. JoinFlowBean.java. Bean gerenciado que tratar especificamente da execuo do fluxo joinFlow.
/** * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. * * You may not modify, use, reproduce, or distribute this software except in * compliance with the terms of the License at: * http://java.net/projects/javaeetutorial/pages/BerkeleyLicense */ package javaeetutorial.checkoutmodule; import java.io.Serializable; import javax.inject.Named; import javax.faces.flow.FlowScoped; import javax.faces.model.SelectItem; /** * Backing bean for JoinFlow. */ @Named @FlowScoped("joinFlow") public class JoinFlowBean implements Serializable { private static final long serialVersionUID = 1L; private boolean fanClub;

private String[] newsletters; private static final SelectItem[] newsletterItems = { new SelectItem("Duke's Quarterly"), new SelectItem("Innovator's Almanac"), new SelectItem("Duke's Diet and Exercise Journal"), new SelectItem("Random Ramblings") }; public JoinFlowBean() { this.newsletters = new String[0]; } public String getReturnValue() { return "/exithome"; } public boolean isFanClub() { return fanClub; } public void setFanClub(boolean fanClub) { this.fanClub = fanClub; } public String[] getNewsletters() { return newsletters; } public void setNewsletters(String[] newsletters) { this.newsletters = newsletters; } public SelectItem[] getNewsletterItems() { return newsletterItems; } }

Listagem 10. joinFlow2.xhtml. Segunda e ltima pgina do fluxo de nome joinFlow.


<?xml version='1.0' encoding='UTF-8' ?> <!-Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. You may not modify, use, reproduce, or distribute this software except in compliance with --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" the terms of the License at: http://java.net/projects/javaeetutorial/pages/BerkeleyLicense

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <h:outputStylesheet library="css" name="stylesheet.css"/> <title>Join Flow Page Two</title> </h:head> <h:body style="background-color: lightgoldenrodyellow"> <h:form prependId="false"> <h:graphicImage url="#{resource['images:duke.books.gif']}" alt="Duke carrying books"/> <h2>Join Flow Page Two</h2> <p>Thank you, #{flowScope.param1Value}! Reading the parameter passed from the Checkout flow.</p> <p>To call the checkout flow, click Check Out.</p> <p>To go to the site's home page or to return to the calling flow, click Home.</p> <p><h:commandButton value="Check Out" action="callcheckoutFlow"/></p> <p><h:commandButton value="Exit Flow" action="returnFromJoinFlow"/></p> </h:form> </h:body> </html>

Vamos, agora, dedicar algumas palavras ao processo de checkout (checkoutFlow). A mudana, neste caso, est na configurao do fluxo, que, diferentemente do modelo declarativo de joinFlow, ser definido programaticamente a partir da API de Faces Flow. Na Listagem 11, apresentamos a pgina de entrada deste fluxo que, da mesma forma que em joinFlow, tida como n de entrada do fluxo por levar o seu nome. Alm disso, assim como tambm foi feito no fluxo apresentado anteriormente, h parmetros de entrada sendo recebidos na view a partir do objeto de fluxo de escopo mantido pelo framework. A Listagem 12 contm uma classe na qual o fluxo , ento, configurado. A API central de Faces Flow est definida em javax.faces.flow.builder.FlowBuilder. A partir de uma instncia desta classe, somos capazes de fazer tudo aquilo que conseguimos atravs de um arquivo XML, como o visto na Listagem 7, em cdigo Java. Na verdade, quando optamos pela configurao declarativa, estamos delegando ao framework JSF a construo do fluxo em questo, o que, por sua vez, acaba resultando em uma chamada a esta API, de forma transparente. Listagem 11. checkoutFlow.xhtml. Ponto de entrada do fluxo de checkout.
<?xml version='1.0' encoding='UTF-8' ?> <!--

Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. You may not modify, use, reproduce, or distribute this software except in compliance with --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <h:outputStylesheet library="css" name="stylesheet.css"/> <title>Checkout Flow Page One</title> </h:head> <h:body style="background-color: lightblue"> <h:form prependId="false"> <h:graphicImage url="#{resource['images:duke.books.gif']}" alt="Duke carrying books"/> <h2>Checkout Flow Page One</h2> <p>Thank you for your order of #{checkoutBean.numItems} books at a cost of <h:outputText value="#{checkoutBean.cost}"> <f:convertNumber currencySymbol="$" type="currency"/> </h:outputText>.</p> <p>Please provide your shipping information. Required fields are marked with an asterisk (*).</p> <h3>Shipping Information</h3> <h:panelGrid columns="3" role="presentation"> <h:outputLabel value="Name: * " for="name"/> <h:inputText id="name" value="#{checkoutFlowBean.name}" required="true"/> <h:message for="name" style="color: #D20005"/> <h:outputLabel value="Address Line 1: * " for="addr1"/> <h:inputText id="addr1" value="#{checkoutFlowBean.addressLine1}" required="true"/> <h:message for="addr1" style="color: #D20005"/> <h:outputLabel value="Address Line 2:" for="addr2"/> <h:inputText id="addr2" value="#{checkoutFlowBean.addressLine2}"/> <h:message for="addr2" style="color: #D20005"/> the terms of the License at: http://java.net/projects/javaeetutorial/pages/BerkeleyLicense

<h:outputLabel value="City: * " for="city"/> <h:inputText id="city" value="#{checkoutFlowBean.city}" required="true"/> <h:message for="city" style="color: #D20005"/> <h:outputLabel value="State:" for="state"/> <h:inputText id="state" value="#{checkoutFlowBean.state}" maxlength="2"/> <h:message for="state" style="color: #D20005"/> <h:outputLabel value="Zip/Postcode: * " for="zip"/> <h:inputText id="zip" value="#{checkoutFlowBean.postalCode}" required="true"/> <h:message for="zip" style="color: #D20005"/> <h:outputLabel value="Country: * " for="country"/> <h:inputText id="country" value="#{checkoutFlowBean.country}" required="true"/> <h:message for="country" style="color: #D20005"/> </h:panelGrid> <p>If you called this flow from the Join flow, you can see these parameters: "<h:outputText value="#{flowScope.param1Value}"/>" and "<h:outputText value="#{flowScope.param2Value}"/>" </p> <p>Click Continue to move to the next page of the flow.</p> <p>Click Cancel to exit the flow and return to the starting page.</p> <p></p> <p><h:commandButton value="Continue" action="checkoutFlow2"/></p> <p><h:commandButton value="Exit Flow" action="returnFromCheckoutFlow"/></p> </h:form> </h:body> </html>

Listagem 12. CheckoutFLow.java. Classe usada para se configurar o fluxo de checkout programaticamente.
/** * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. * * You may not modify, use, reproduce, or distribute this software except in * compliance with the terms of the License at: * http://java.net/projects/javaeetutorial/pages/BerkeleyLicense

*/ package javaeetutorial.checkoutmodule; import java.io.Serializable; import javax.enterprise.inject.Produces; import javax.faces.flow.Flow; import javax.faces.flow.builder.FlowBuilder; import javax.faces.flow.builder.FlowBuilderParameter; import javax.faces.flow.builder.FlowDefinition; public class CheckoutFlow implements Serializable { private static final long serialVersionUID = 1L; @Produces @FlowDefinition public Flow defineFlow(@FlowBuilderParameter FlowBuilder flowBuilder) { String flowId = "checkoutFlow"; flowBuilder.id("", flowId); flowBuilder.viewNode(flowId, "/" + flowId + "/" + flowId + ".xhtml"). markAsStartNode(); flowBuilder.returnNode("returnFromCheckoutFlow"). fromOutcome("#{checkoutFlowBean.returnValue}"); flowBuilder.inboundParameter("param1FromJoinFlow", "#{flowScope.param1Value}"); flowBuilder.inboundParameter("param2FromJoinFlow", "#{flowScope.param2Value}"); flowBuilder.flowCallNode("calljoin").flowReference("", "joinFlow"). outboundParameter("param1FromCheckoutFlow", "#{checkoutFlowBean.name}"). outboundParameter("param2FromCheckoutFlow", "#{checkoutFlowBean.city}"); return flowBuilder.getFlow(); } }

Toda vez que quisermos definir, em nossos sistemas, um mtodo produtor de fluxos JSF, deveremos seguir os passos listados a seguir: O mtodo precisa ser configurado @javax.enterprise.inject.Produces; como produtor, atravs da anotao CDI

O mtodo precisa ser configurado, tambm, com a anotao @javax.faces.flow.builder.FlowDefinition, que garante que o que ser produzido pelo mtodo em questo um fluxo (javax.faces.flow.Flow);

O mtodo deve retornar uma instncia de javax.faces.flow.Flow; O mtodo deve receber, por parmetro, uma instncia de javax.faces.flow.builder.FlowBuilder, que ser usado para configurar, de fato, o fluxo em questo; Pelo cdigo da Listagem 12, o leitor pode perceber que o que feito ali exatamente aquilo que j vimos no arquivo XML apresentado na Listagem 7. Por este motivo, no investiremos tempo em analisar o contedo deste mtodo. Na Listagem 13, apresentamos o n de sada de checkoutFlow, que em muito se assemelha ao contedo da Listagem 10. Vemos, ali, uma ao mapeada para sada de checkoutFlow e tambm uma ao de entrada para joinFlow, que estabelece uma comunicao entre esses dois fluxos no sentido inverso ao que j vimos quando analisamos joinFlow. Listagem 13. checkoutFlow4.xhtml. ltima pgina do fluxo de checkout.
<?xml version='1.0' encoding='UTF-8' ?> <!-Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. You may not modify, use, reproduce, or distribute this software except in compliance with --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <h:outputStylesheet library="css" name="stylesheet.css"/> <title>Checkout Flow Page Four</title> </h:head> <h:body style="background-color: lightblue"> <h:form prependId="false"> <h:graphicImage url="#{resource['images:duke.books.gif']}" alt="Duke carrying books"/> <h2>Checkout Flow Page Four</h2> <p>Thank you for your order, <h:outputText value="#{checkoutFlowBean.name}"/>!</p> <p>Your order will be billed to <h:outputText value="#{checkoutFlowBean.ccName}"/>.</p> <p>To join our mailing list or club, click Join. This action will call the Join flow.</p> <p>To return to the index page or to the first page of the calling flow, click Return.</p> <p><h:commandButton value="Join" action="calljoin"/></p> <p><h:commandButton value="Exit Flow" action="returnFromCheckoutFlow"/></p> the terms of the License at: http://java.net/projects/javaeetutorial/pages/BerkeleyLicense

</h:form> </h:body> </html>

As Listagens 14 e 15 foram apresentadas aqui apenas para fecharmos a composio dos ciclos. A Listagem 14 mostra a pgina de entrada da aplicao, onde cada um dos botes nela includos aponta para os fluxos que vimos at o momento. A ao desses botes esttica e tem como valor o nome dos ns iniciais de cada fluxo. Uma vez que essas pginas sejam acessadas, pela conveno que j foi apresentada ao leitor anteriormente, detectada a entrada em um fluxo, que passar a ser executado. A Listagem 15, por sua vez, uma pgina que representa o n de sada do fluxo joinFlow, que contm um boto que redireciona o usurio para a pgina inicial, j citada, contida na Listagem 14. Listagem 14. Index.xhtml. Pgina inicial da aplicao.
<!-Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. You may not modify, use, reproduce, or distribute this software except in compliance with --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <h:outputStylesheet library="css" name="stylesheet.css"/> <title>Checkout Module: Entry Page (Order)</title> </h:head> <h:body> <h:form prependId="false"> <h:graphicImage url="#{resource['images:duke.books.gif']}" alt="Duke carrying books"/> <h2>Order Page</h2> <p>You have ordered #{checkoutBean.numItems} books at a cost of <h:outputText value="#{checkoutBean.cost}"> <f:convertNumber currencySymbol="$" type="currency"/> </h:outputText>.</p> <p>Click Check Out to check out your order and enter the checkout flow.</p> <p><h:commandButton value="Check Out" action="checkoutFlow"/></p> the terms of the License at: http://java.net/projects/javaeetutorial/pages/BerkeleyLicense

<p>Click Join to join our mailing list or club and enter the join flow.</p> <p><h:commandButton value="Join" action="joinFlow"/></p> <p>This page is the exit point for the checkout flow pages.</p> </h:form> </h:body> </html>

Listagem 15. exitHome.xhtml. Pgina de sada do fluxo intitulado joinFlow.


<?xml version='1.0' encoding='UTF-8' ?> <!-Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. You may not modify, use, reproduce, or distribute this software except in compliance with --> <!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:h="http://xmlns.jcp.org/jsf/html"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <h:outputStylesheet library="css" name="stylesheet.css"/> <title>Checkout Module: Exit Page (Home)</title> </h:head> <h:body> <h:form> <h:graphicImage url="#{resource['images:duke.books.gif']}" alt="Duke carrying books"/> <h2>Home/Exit Page</h2> <p>Imagine that this is the home page of the company. When you exit the join flow pages, you land here.</p> <p><h:commandButton value="Go to Checkout Page" action="index"/></p> </h:form> </h:body> </html> the terms of the License at: http://java.net/projects/javaeetutorial/pages/BerkeleyLicense

Concluso Chegamos ao final do primeiro artigo da srie sobre as novidades do JSF 2.2. Ao longo do texto, vimos duas das mais significativas caractersticas incorporadas especificao, que abrem agora a chance de se trabalhar nativamente com fluxos e permitem, tambm, que se explore de forma livre e plena os recursos do HTML 5 no desenvolvimento da interface grfica de aplicaes JSF. Essas so duas das quatro

caractersticas mais impactantes desta reviso do framework, restando ainda outras duas a serem abordadas no ltimo artigo da srie. Nele, trataremos em detalhes o conceito de views stateless e toda a discusso que esta questo gera. Esta uma solicitao antiga de muitos desenvolvedores, que viram, ainda que de forma reduzida, o seu pedido finalmente atendido. Veremos, ainda, como funciona um mecanismo intitulado contratos de bibliotecas de recursos, cuja ideia a de suportar mltiplos templates dentro de uma aplicao Java para web. Encerraremos o segundo artigo com algumas palavras sobre outra caracterstica que, embora no tenha o rtulo de Big Ticket, ser de grande valor para a comunidade de desenvolvedores, facilitando significativamente o trabalho com o recurso de upload de arquivos em aplicaes web baseadas em JSF. Desde j, gostaramos de deixar novamente o convite para que o leitor consulte a documentao oficial da JSR-344, cujo endereo pode ser encontrado na seo Links. Nela possvel termos uma noo mais plena de todo o volume de trabalho realizado em cima do JSF, e o quanto tudo o que foi incorporado contribui no sentido de entregar, comunidade, um framework ainda mais robusto, poderoso, flexvel e completo. Por enquanto, desejamos ao leitor um bom divertimento com o contedo abordado at aqui, e deixamos marcado um encontro, muito em breve, para fecharmos este nosso estudo em cima das novidades do JavaServer Faces. At l!

A renovao do JSF Parte 2


Neste artigo abordaremos trs outras caractersticas centrais do JSF 2.2, cobrindo todos os pontos classificados, na especificao, como Big Ticket Features, fechando assim uma anlise em torno de todas as novidades mais relevantes.
A renovao do JSF Parte 2 JavaServer Faces, o framework mais popular da especificao Java EE para o desenvolvimento da camada de apresentao em sistemas web, foi atualizado. No primeiro artigo desta srie, estudamos duas das mais relevantes mudanas trazidas com a nova verso: uma perspectiva de desenvolvimento orientado a fluxos (Faces Flow) e marcadores amigveis HTML 5, permitindo o uso desta linguagem em substituio Facelets na estruturao de views/pginas, quando desejado e/ou necessrio. No texto que se segue, abordaremos trs outras caractersticas centrais do JSF 2.2, cobrindo todos os pontos classificados, na especificao, como Big Ticket Features, fechando assim uma anlise em torno de t odas as novidades mais relevantes encontradas nesta nova verso do framework.

Em que situao o tema til Este tema ser til para todo desenvolvedor web que utilize Java como tecnologia-alvo. Ser igualmente proveitoso para todo entusiasta de tecnologias web que gosta de se manter atualizado sobre a evoluo dos frameworks mais populares do mercado ao longo do tempo. No primeiro artigo desta srie, analisamos uma caracterstica bastante til chamada Faces Flow. A partir dela, passamos a contar com suporte nativo, em Java EE, para o desenvolvimento de aplicaes orientadas a

fluxos, algo indito at ento e projetado a partir das melhores prticas e melhores recursos presentes em frameworks de mercado que j trabalham neste modelo. Estudamos, tambm, a flexibilizao da especificao JSF no tocante construo de interfaces com o usurio a partir do recurso intitulado HTML Friendly Markups (ou, traduzido para o portugus, marcadores amigveis HTML 5). Por ele, passa a ser possvel contornarmos o modelo padro de desenvolvimento de views, substituindo a linguagem Facelets por HTML e, ainda assim, utilizarmos todos os benefcios dos servios oferecidos pelo framework no ambiente servidor (como a representao de views a partir de rvores de componentes, preservao do estado dessas views, validaes, converses, dentre outros). Neste ltimo artigo, veremos outras trs importantes novidades do JSF 2.2. Ao longo do texto, o leitor tomar contato com um novo componente projetado especificamente para a carga de arquivos (file upload), uma estratgia para configurar e trabalhar com views stateless e, ainda, uma tcnica para a construo e utilizao de mltiplos templates dentro de uma mesma aplicao. Carregando arquivos no servidor com JSF Carregar arquivos da camada cliente para a camada servidora nunca foi um recurso nativo no JavaServer Faces. Para que nossas aplicaes apresentassem este tipo de caracterstica para o usurio final, tnhamos que recorrer a dependncias externas, dentre as quais a mais popular a Apache Commons FileUpload (veja a seo Links). Mesmo em implementaes mais sofisticadas da especificao, como o caso do PrimeFaces, o componente que apresenta este recurso pronto para o desenvolvedor utiliza, implicitamente, essas mesmas dependncias. Para comearmos a analisar este novo componente para carga de arquivos trazido pelo JSF 2.2, precisamos compreender, com clareza, o ambiente no qual est inserido. Este recurso do framework tem sua base estabelecida no suporte a multipart da Servlet API 3.0, o que significa que: O controlador frontal do JSF, javax.faces.webapp.FacesServlet , agora, configurado com a anotao @MultipartConfig da Servlet API 3.0 (JSR-315), tornando possvel o tratamento de requisies cujo contedo tenha sido codificado como multipart/form-data; Esta configurao descrita no item acima gera uma dependncia do JSF em relao Servlet API 3.0, como j havamos antecipado no incio do artigo anterior. Todo formulrio cujo tipo de codificao de contedo seja multipart-form-data submeter os dados nele contido como uma grande stream de dados preparada de modo que cada campo seja representado como uma parte. Toda parte, por sua vez, conter no apenas o contedo definido, mas tambm, metadados como tamanho, nome de arquivo (quando aplicvel), dentre outros. Dentro dessa stream de dados, enviada na requisio, so usadas strings delimitadoras de incio e de fim. Assim, no ambiente servidor, ser possvel separar os dados e metadados de cada campo para, ento, process-los adequadamente. Uma parte, na Servlet API 3.0, representada pela interface javax.servlet.http.Part. De acordo com sua documentao oficial, esta interface representa uma parte ou um item de um formulrio recebida(o) a partir de uma requisio cujo mtodo seja POST e cujo tipo de encoding seja multipart/form-data. Sem nos demorarmos mais em teoria, vamos ento para um estudo de caso. Comearemos pela Listagem 1, que contm um formulrio no qual usamos o novo componente criado para upload de arquivos, cujo marcador atende por <h:inputFile> e pertence ao espao de nomes de elementos HTML da JSF (http://xmlns.jcp.org/jsf/html). Ainda sobre este formulrio, importante nos atentarmos para alguns fatos: Conforme requisito j levantado, a codificao de seu contedo foi configurada como multipart/form-data;

O campo de carregamento de arquivo (<h:inputFile>) ter seu valor associado a um campo de um bean gerenciado (cujo cdigo veremos em instantes), atravs da j conhecida notao da Expression Language; Todo arquivo carregado e submetido dever ser representado logicamente por uma instncia de javax.servlet.http.Part, dada a dependncia j mencionada do JSF pela Servlet API. Listagem 1. index.xhtml. Pgina inicial da aplicao que demonstra a carga de arquivos em JSF 2.2.
<?xml version='1.0' encoding='UTF-8' ?> <!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:h="http://xmlns.jcp.org/jsf/html"> <h:head> <title>Testando o upload de arquivos com JSF 2.2</title> </h:head> <h:body> <h:form prependId="false" enctype="multipart/form-data" > <h:panelGrid columns="2" > <h:outputText value="Entre com o arquivo:" /> <h:inputFile value="#{uploadBean.arquivo}" /> <h:commandButton value="Enviar arquivo" action="#{uploadBean.carregarArquivo()}" /> </h:panelGrid> </h:form> </h:body> </html>

Observe a Listagem 2. Nela, encontramos o cdigo-fonte do bean gerenciado citado no segundo item da lista de marcadores do pargrafo anterior. H um atributo nesta classe, chamado arquivo, que exatamente aquele usado pelo formulrio para transmitir o arquivo escolhido por um usurio para carga. Este atributo, como j sentenciado no terceiro item da lista acima, deve ter como tipo javax.servlet.http.Part, pelas condies j explicadas. Listagem 2.UploadBean.java. Bean gerenciado que realiza a carga de arquivos no servidor.
package br.com.devmedia.uploadapp.mbeans; import java.io.File; import java.io.IOException; import java.io.Serializable; import javax.enterprise.context.SessionScoped; import javax.inject.Named; import javax.servlet.http.Part; /** * Bean gerenciado utilizado para exemplificar o uso do suporte nativo da * especificao JavaServer Faces 2.2 no tratamento a upload de arquivos. *

* @author pedrobrigatto */ @Named(value = "uploadBean") @SessionScoped public class UploadBean implements Serializable { /** * Atributo usado para receber o arquivo selecionado pelo usurio */ private Part arquivo; /** * Mtodo usado pela view para submeter o formulrio preenchido pelo * usurio. * * @return Um outcome usado pela aplicao para determinar a prxima view. * @throws IOException Caso algum problema na escrita do arquivo ocorra. */ public String carregarArquivo() throws IOException { String nomeArquivoSubmetido = arquivo.getSubmittedFileName(); System.out.println(String.format( "Valor da propriedade submittedFileName antes do parse: %s", nomeArquivoSubmetido)); formatarNome(nomeArquivoSubmetido); System.out.println(String.format( "Valor da propriedade submittedFileName depois do parse: %s", nomeArquivoSubmetido)); // Usando modelo anterior a Servlets API 3.1, a partir do cabealho. String nomeArquivo = lerNomeArquivo(arquivo); arquivo.write(nomeArquivo); return "success"; } /** * Mtodo usado para obter o nome do arquivo a partir de uma coleo de * campos de cabealho identificado pelo nome "content-disposition". * * @param arquivo Parte do formulrio que guarda um arquivo a ser * armazenado. * @return O nome do arquivo, guardando no cabealho. * @throws IOException Caso algum problema de leitura desta parte do * formulrio ocorra. */ private String lerNomeArquivo(Part arquivo) throws IOException {

String nomeObtido = null; String[] dadosCD = arquivo.getHeader("content-disposition").split(";"); for (String cd : dadosCD) { if (cd.trim().startsWith("filename")) { System.out.println(String.format("Atributo do cabealho: %s", cd)); // Removendo as aspas duplas que envolvem o nome do arquivo. String nomeArquivo = cd.substring(cd.indexOf("=") + 1). trim().replace("\"", ""); System.out.println(String.format("Valor guardado pelo atributo: %s", nomeArquivo)); formatarNome(nomeArquivo); nomeObtido = nomeArquivo; break; } } return nomeObtido; } private void formatarNome(String nomeArquivo) { // Recuperando o texto imediatamente aps a ocorrncia da ltima barra. nomeArquivo = nomeArquivo.substring( nomeArquivo.lastIndexOf(File.separatorChar) + 1); System.out.println(String.format("Atributo do cabealho: %s", nomeArquivo)); } public Part getArquivo() { return arquivo; } public void setArquivo(Part arquivo) { this.arquivo = arquivo; } }

Esta interface , por si s, suficiente para representar todas as informaes de um arquivo, de seu contedo a seu nome e tamanho. Na Java EE 6, esta interface ainda no continha um mtodo cuja assinatura a seguinte: getSubmittedFileName() : String Este mtodo foi incorporado na Servlet API 3.1, que outro conjunto de melhorias/correes trazido com a Java EE 7. Na verso anterior, era necessrio implementarmos uma lgica na qual tomvamos um item de cabealho especfico, de identificador content-disposition e, a partir dele, verificvamos o campo de nome filename. Atualmente, a execuo do mtodo acima exposto mostrou-se equivalente lgica anteriormente empregada, de modo que uma invocao a ele , a partir de agora, suficiente para obtermos o nome do arquivo submetido por um usurio.

De qualquer maneira, esta lgica foi inserida no cdigo da Listagem 2, de modo que o leitor tenha acesso ao modelo antigo de se recuperar o nome de arquivos. Quando depuramos a aplicao e analisamos este item de cabealho com calma, vemos que so trs os campos retornados. So eles: form-data: indica o tipo de codificao de contedo; name: fornece o ID do campo na rvore de componentes da view; filename: fornece o nome do arquivo submetido. Usando esta abordagem, portanto, basta que percorramos este array de elementos e capturemos o valor guardado pela clula identificada por filename. Ao encontr-la, partimos para o processamento de seu contedo, de modo a garantir que, independente do sistema operacional no qual estivermos trabalhando, tenhamos extrado seu valor corretamente. O processo de escrita do arquivo em disco, no ambiente servidor, bastante simplificado com o uso da API de javax.servlet.http.Part. Ainda na Listagem 2, vemos que a ltima instruo do mtodo carregarArquivo() consiste em uma chamada a um mtodo desta API, cuja assinatura a seguinte: write (String filename) : void sendo filename o nome do arquivo obtido de uma dentre as duas maneiras j citadas e, aqui, somente reforadas: Recuperando-se um campo definido no cabealho de ID content-disposition; Recuperando-se o nome deste arquivo javax.servlet.http.Part#geSubmitedFileName(). por meio de uma chamada ao mtodo

Isto, por si s, suficiente para que o arquivo seja gravado em disco, em um caminho relativo quele especificado na anotao @MultipartConfig. No caso da implementao de FacesServlet que usamos (Mojarra), o caminho pr-estabelecido para arquivos <home_do_servidor >/glassfish/domains/<dominio>/generated/jsp. importante, ainda, mencionarmos que o servidor de aplicaes que usamos em nossos testes o GlassFish 4. Com o sucesso do upload do arquivo, ser apresentada ao usurio uma view de sucesso, cujo cdigo podemos ver na Listagem 3. Nela, tambm temos um comando que permite voltarmos view da Listagem 1, para executarmos novamente todo o processo em uma nova carga. Listagem 3. success.xhtml. Pgina de sada quando a carga de arquivos for bem sucedida.
<?xml version='1.0' encoding='UTF-8' ?> <!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:h="http://xmlns.jcp.org/jsf/html"> <h:head> <title>Testando o File Upload da JSF 2.2</title> </h:head> <h:body> <h:form prependId="false" >

Upload realizado com sucesso!!!!!!!!!! <br /><br /> <h:commandButton value="Voltar" action="index" /> </h:form> </h:body> </html>

E, assim, cobrimos o recurso de upload de arquivos que o JSF passou a suportar, desde sua verso 2.2, nativamente, como parte integrante de sua especificao. Como vimos, os primeiros passos com este novo recurso so bastante simples de serem seguidos, ponto muito positivo para que passemos a adot-lo em nossas prximas solues. Contratos de bibliotecas de recursos Neste tpico, analisaremos outra caracterstica do JavaServer Faces rotulada como Big Ticket Feature. No primeiro artigo da srie, j vimos duas delas, a saber: Faces Flow e HTML Friendly Markups. Agora, a vez de falarmos do que se chamou de Resource Library Contracts, ou contratos de bibliotecas de recursos. Como j sabemos, algumas caractersticas planejadas para o JSF 2.2 acabaram sendo prejudicadas por terem sido iniciadas muito tardiamente. Em alguns casos, tais caractersticas foram totalmente postergadas, enquanto, em outros, sofreram reduo de escopo para que pudessem, ainda que sem a sofisticao planejada, ser incorporadas na especificao. Este o caso do que, originalmente, deveria se chamar Multitemplating, caracterstica muito relevante que ainda no teremos como ver funcionando em sua plenitude. Em linhas gerais esta proposta visa permitir: Que se defina mltiplos templates para um mesmo projeto, empacotando-os de forma independente das aplicaes que deles faam uso; O suporte on-the-fly para mudana de temas, possibilitando a troca de fontes, diagramao e mesmo padro de cores de acordo com a preferncia do usurio, com o sistema em pleno funcionamento; Que usurios criem seus prprios temas e os carreguem na aplicao, de modo que a estilizao das solues JSF seja um processo no mais vinculado apenas a desenvolvedores, mas tambm ao pblico consumidor de solues baseadas em JSF. A reduo do escopo desta caracterstica fez com que se atribusse, ao trabalho, o ttulo mencionado no incio deste tpico: Resource Library Contracts. Embora tenha sido entregue algo muito menor do que o inicialmente planejado, o que temos em mos j , sem dvidas, muito rico. Tudo gira em torno do conceito de contratos. Mas, afinal, o que so? Para ajud-lo a entender, faremos uso da Figura 1. Todo contrato composto, como se v na ilustrao, por trs elementos: 1. Recursos: imagens, arquivos contendo pginas de estilo, dentre outros; 2. Templates: os modelos de views propriamente ditos, que estabelecem como o contedo ser apresentado para o usurio final; 3. Pontos de insero: pontos, nesses modelos j citados, configurados para acomodar contedo das diversas views que compem o sistema;

Figura 1. Diagrama representando a estrutura de contratos. Um dos pontos fortes da estratgia de definio de contratos que cada um pode ser empacotado separadamente dos demais. Seguindo a ilustrao proposta na Figura 1, poderamos ter trs arquivos JAR contendo, cada qual, o contedo correspondente a um contrato. Estes, por sua vez, poderiam ser utilizados no apenas no projeto que veremos adiante, mas em tantos outros projetos em que pudessem ser teis. Apresentado o conceito, passemos para um estudo mais prtico. Antes, porm, convidamos o leitor a dedicar alguma ateno Figura 2. Nela, temos a estrutura de um projeto criado a partir da IDE NetBeans que, embora esteja oficialmente na verso 7.3.1, j est com a verso 7.4 Beta disponvel para download. Nela, encontramos suporte direto criao de contratos, em que a prpria IDE monta para ns a estrutura de diretrios de acordo com a conveno especificada. Esta conveno dita que, em um projeto em Java para a web, todo contrato deve ser criado dentro de um novo diretrio denominado contracts; diz, tambm, que o nome que se d ao diretrio referente ao contrato ser o nome do contrato em questo. Na Figura 2, de acordo com o que acabamos de ver, temos um exemplo de dois contratos distintos, de nomes contrato1 e contrato2.

Figura 2. Estrutura do projeto para estudo de Contratos de Bibliotecas de Recursos do JSF. A Listagem 4 nos apresenta o template definido para o contrato de nome contrato1. Nela, o leitor perceber que existe um ponto de insero, identificado pelo nome conteudo, que ser usado para, em tempo de execuo, acomodar um contedo de acordo com a view que for apresentada ao usurio. A Listagem 5, por sua vez, mostra outro template, definido para o contrato de nome contrato2, que difere do primeiro apenas na cor de fundo e em alguns poucos textos que sero apresentados ao usurio. Novamente, o mesmo ponto de insero, com o mesmo nome que o primeiro, aparece no template. Veremos, a seguir, que o fato do

ponto de insero ser identificado pelo mesmo nome nos dois templates ser um ponto decisivo no comportamento da aplicao. Listagem 4. template.xhtml. Template definido para o primeiro contrato da aplicao.
<?xml version='1.0' encoding='UTF-8' ?> <!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:h="http://xmlns.jcp.org/jsf/html" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"> <h:head> <title>Java Server Faces 2.2 - JAVA MAGAZINE</title> </h:head> <h:body style="background-color: brown;"> <p><h2>Testando o uso de templates mltiplos com JSF 2.2 - TEMPLATE 1</h2></p> <p style="color: whitesmoke;"> <h3>Este o primeiro contrato definido para a aplicao</h3> </p> <ui:insert name="conteudo" /> </h:body> </html>

Listagem 5. template.xhtml. Template definido para o segundo contrato da aplicao.


<?xml version='1.0' encoding='UTF-8' ?> <!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:h="http://xmlns.jcp.org/jsf/html" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"> <h:head> <title>Java Server Faces 2.2 - JAVA MAGAZINE</title> </h:head> <h:body style="background-color: blueviolet;"> <p><h2>Testando o uso de templates mltiplos com JSF 2.2 - TEMPLATE 2</h2></p> <p style="color: darkgreen;"> <h3>Este o segundo contrato definido para a aplicao</h3> </p> <ui:insert name="conteudo" /> </h:body> </html>

Passemos, agora, anlise do contedo da Listagem 6. Este um exemplo da aplicao do recurso de contratos em uma view que ser, efetivamente, apresentada ao usurio. Nela, vemos o emprego de um novo

atributo incorporado no JSF 2.2, de nome contracts. Este atributo aplicvel apenas ao elemento <f:view>, sendo compatvel apenas com views escritas a partir da VDL facelets. Logo, pginas/views escritas em HTML ou JSP no se beneficiam desta nova feature. O valor definido para este novo atributo ser usado para identificar o contrato a ser seguido. No exemplo trazido com a Listagem 6, determinamos que o nome do contrato ser especificado em tempo de execuo, de acordo com o valor que um bean gerenciado estiver guardando, em um de seus atributos, naquele momento. Listagem 6. Index.xhtml. View principal, que faz uso do sistema de contratos implementado.
<?xml version='1.0' encoding='UTF-8' ?> <!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:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"> <f:view contracts="#{templateBean.templateSelecionado}" > <ui:composition template="/template.xhtml" > <ui:define name="conteudo" > <h:form prependId="false" > <p bolder;"> O primeiro template foi aplicado, por isso estamos vendo este contedo! </p> <h:commandButton id=btnTroca value="Trocar template" action="#{templateBean.trocarTemplate()}" /> </h:form> </ui:define> </ui:composition> </f:view> </html> style="font-family:Verdana,sans-serif;color: red; font-weight:

Mais abaixo, ainda na Listagem 6, definido o template que ser empregado na composio desta view. No caso, o nome do template fixo, e recebeu o valor de template.xhtml. Na Listagem 7, por sua vez, o que temos um bean gerenciado que, como apresentamos h alguns instantes, responsvel por definir qual ser o contrato aplicado view da Listagem 6. Trata-se da classe TemplateBean, que possui um atributo intitulado templateSelecionado. Esta a varivel de instncia que, por meio da EL (Expression Language), teve seu valor vinculado ao atributo contracts da view. Inicialmente, este atributo de TemplateBean est associado a uma constante esttica identificada como CONTRATO1, de valor, contrato1. Este valor alternado entre os valores contrato1 e contrato2 (este ltimo guardado em outra constante, CONTRATO2) a cada vez que o usurio clicar no boto identificado como btnTroca, da view exibida na Listagem 6.

Listagem 7. TemplateBean.java. Bean gerenciado responsvel por gerenciar a mudana de templates em runtime.
package br.com.devmedia.multitemplate.mbeans; import java.io.Serializable; import javax.enterprise.context.SessionScoped; import javax.inject.Named; /** * Bean gerenciado responsvel por realizar a troca de template da aplicao em * tempo de execuo, demonstrando a caracterstica intitulada "Resource Library * Contracts" da especificao JavaServer Faces 2.2. * * @author pedrobrigatto */ @Named(value = "templateBean") @SessionScoped public class TemplateBean implements Serializable { private static final String CONTRATO1 = "contrato1"; private static final String CONTRATO2 = "contrato2"; private String templateSelecionado = CONTRATO1; public String getTemplateSelecionado() { return templateSelecionado; } public void setTemplateSelecionado(String templateSelecionado) { this.templateSelecionado = templateSelecionado; } /** * Mtodo usado para se trocar o contrato em uso pelo cliente no momento. */ public void trocarTemplate () { if (templateSelecionado != null) { switch (templateSelecionado) { case CONTRATO1: templateSelecionado = CONTRATO2; break; case CONTRATO2: templateSelecionado = CONTRATO1; break; } } else { templateSelecionado = "contrato1";

} } }

Este cenrio flexvel ao ponto de permitir a troca, em tempo de execuo, do contrato seguido pela pgina em exibio. O nvel de flexibilidade seria ainda maior caso a escolha do template fosse tambm dinmica, determinada por um bean gerenciado de acordo com o gosto do usurio. Quando, no exemplo apresentado, fixamos o nome do template como template.xhtml, acabamos obrigados a nomear cada arquivo de template, dentro de cada pasta de contrato, exatamente com este nome, de modo que a aplicao seja capaz de encontrar, para cada contrato selecionado, o modelo a ser seguido pela pgina em exibio. Por fim, apresentamos na Figura 3 o resultado da execuo desta aplicao. Isto tudo o que precisamos saber para comear a trabalhar com mltiplos templates dentro de solues baseadas no JSF 2.2. Embora tudo o que vimos j seja suficiente para o desenvolvimento de solues interessantes, importante que o leitor fique atento s novidades que viro na prxima edio da especificao JSF. Como dito no incio, esta uma das tantas caractersticas incorporadas no framework com um escopo significativamente reduzido em relao ao projeto original. importante que fiquemos atentos, pois uma nova reviso desta especificao trar, certamente, ainda mais poder no que tange ao recurso de mltiplos templates em Java para a web. A seguir, vamos examinar a ltima das grandes caractersticas do JSF 2.2, que o conceito de views sem estado (stateless views).

Figura 3. Demonstrao do uso de dois templates aplicados a uma mesma view. Stateless views J sabemos, dos conceitos vistos no primeiro artigo desta srie, que em JSF h uma preservao do estado de cada componente e, consequentemente, da view como um todo, no ambiente servidor. Esta uma caracterstica que no causa incmodo maioria dos desenvolvedores na esmagadora maioria dos casos, mas constantemente foco de discusso entre outros, que levantam para debate alguns pontos mais sensveis, como: 1. Guardar o estado da view pode ser prejudicial para o desempenho da aplicao;

2. O consumo de memria acaba se tornando abusivo a partir de frameworks que guardam o estado de views, uma vez que esta uma informao adicional que, para toda view, sempre deve ser considerada; 3. Guardar o estado de views gera uma srie de inconvenientes no tocante a excees com relao s views expiradas; 4. Manter o estado das views impede o roteamento de requisies entre mquinas servidoras executando uma aplicao JSF em um contexto de clusters e suporte a failover. No contexto das mquinas servidoras dos dias de hoje, um grande exagero (e, cabe dizer, at certo preciosismo) falar em prejuzo tanto no consumo de memria quanto no desempenho da aplicao, pois um estado de uma view, representado no ambiente servidor, definitivamente no traz qualquer degradao para o ambiente em si. No entanto, os outros dois pontos merecem uma ateno especial, principalmente aquele que diz respeito questo do ambiente de failover. Portanto, dedicaremos um foco maior sobre esses dois itens a partir de agora. Sobre expirao de views Sempre que uma pgina requisitada por um usurio e, por algum motivo, ela no se encontra mais salva na sesso, podemos nos deparar com uma situao de view expirada, sinalizada pela runtime do JSF como uma instncia de javax.faces.application.ViewExpiredException. Um exemplo clssico em que isso acontece aquele em que o sistema permaneceu ocioso por um longo tempo, excedendo o tempo mximo de sesso configurado. O processo razoavelmente simples de entender, e falaremos um pouco sobre ele antes de prosseguirmos. J abordamos o ciclo de vida de uma requisio JSF em detalhes no primeiro artigo, e focaremos mais especificamente na primeira daquelas etapas, conhecida como Restaurao de uma view. Este o momento em que casos de expirao de views podem ocorrer. Tudo comea quando uma view precisa ser recuperada (montada ou restaurada), processo conduzido pela instncia de javax.faces.application.ViewHandler mantida pelo singleton javax.faces.application.Application, que representa a aplicao propriamente dita. O mtodo invocado, aqui, o initView(FacesContext), processado antes mesmo do ciclo de vida JSF ser iniciado. Caso esta requisio seja do tipo postback (ou seja, trata-se de uma view j visitada anteriormente, qual se est retornando), o fluxo segue em frente a partir de uma tentativa, pela j citada instncia de ViewHandler, de restaurar a view, o que executado a partir da invocao do mtodo restoreView(FacesContext contexto, String viewId), em que viewId o identificador da view envolvida na requisio corrente. O retorno deste mtodo uma instncia de javax.faces.component.UIViewRoot, que representa a rvore de componentes da view identificada pelo ID fornecido. Sempre que, entretanto, obtivermos como resultado da execuo deste mtodo um ponteiro nulo, estaremos diante de um caso em que a view desejada no pde ser encontrada. Este um caso que, pela especificao, estaremos sujeitos ao lanamento de uma instncia da classe javax.faces.application.ViewExpiredApplication. Nos casos em que a requisio no de um postback, haver a tentativa de se recuperar a instncia de javax.faces.view.ViewDeclarationLanguage da view desejada. Esta busca comea a partir de uma chamada a um mtodo da instncia de ViewHandler de assinatura deriveLogicalViewId(FacesContext contexto, String rawViewID), cujo papel o de retornar o identificador da view a partir de um valor bruto passado pela requisio que, quando submetido a um algoritmo interno de ViewHandler, resulta no identificador da view em questo. Este algoritmo no ser detalhado aqui, mas pode ser encontrado na documentao oficial da JSR-344 (cujo endereo se encontra na seo Links).

De posse do identificador da view, o prximo passo obter a instncia de ViewDeclarationLanguage a partir dele, o que feito invocando-se o mtodo, tambm da instncia de ViewHandler, chamado getViewDeclarationLanguage(FacesContext contexto, String viewId). Se nenhuma instncia de ViewDeclarationLanguage puder ser obtida pela chamada ao mtodo mencionado, o processo de renderizao da resposta ser imediatamente acionado. Caso contrrio, haver uma sequncia de passos (identificao de metadados, criao de uma view a partir desses metadados, dentre outros) que culminaro na criao da view desejada e, por fim, na execuo da fase de renderizao da resposta. De uma forma ou de outra, o ponto importante aqui que, dados contextos de longo perodo da aplicao em modo de repouso (ou seja, um intervalo de tempo razoavelmente longo em que, muito embora a aplicao esteja aberta em um navegador, no esteja sendo usada) ou mesmo um longo perodo em que uma view j visitada no novamente apresentada ao usurio, teremos configurados cenrios em que a view em questo pode se encontrar expirada. Nessas situaes, invariavelmente, uma exceo ser lanada e, em ltima instncia, ter que ser tratada devidamente para no resultar em uma experincia frustrante para o usurio. Este um problema que surge exatamente pelo fato de que o JSF um framework web que, como tantos outros, preocupa-se com a preservao do estado da view em ambiente servidor. Existem muitos pontos positivos nesta abordagem, sendo que a esmagadora maioria dos desenvolvedores no apresenta queixa alguma sobre este recurso. Entretanto, uma parcela da comunidade vem questionando, frequentemente e h um bom tempo, os motivos pelos quais no se inclua o suporte a views sem estado no framework. Com o JSF 2.2, aps a longa insistncia e, tambm, a fora do argumento associado expirao de views, temos finalmente um primeiro passo caminhando neste sentido. Sobre ambientes rodando em cluster Em ambientes tolerantes a falhas, muito comum trabalharmos com clusters de servidores e aplicarmos algoritmos de balanceamento de carga entre eles. Dessa maneira, garantimos que o sistema estar sempre disponvel a seus usurios, independentemente da carga de requisies que se aplique a ele. Em JSF, ao guardarmos o estado de uma view na sesso, criamos um vnculo entre ela e o n (mquina servidora) que a gerou. Logo, quando o usurio retorna view j criada, obrigatrio que isso seja feito pelo mesmo n que a originou. Se este n, por algum motivo, estiver indisponvel, estaremos diante de um problema. Da mesma forma, caso este n esteja sobrecarregado e esta view seja novamente acessada por um usurio, estaremos impedidos de trabalhar com balanceamento de carga e poderemos, por isso, ter que enfrentar problemas como lentido, indisponibilidade, dentre outros. Remover ns dinamicamente de um cluster tambm pode ser muito complicado quando temos views que guardam estado, pelos mesmos motivos j levantados. Embora haja contornos possveis para os dois problemas acima mencionados, nunca resolvero, de fato, o problema. Logo, encontramos neles justificativas razoveis para o suporte a views sem estado. A soluo para esta necessidade levantada pela comunidade foi obtida s pressas e incorporada tardiamente na especificao. Embora fosse um recurso programado para ser apresentado a partir do JSF 2.2, os trabalhos em torno desta caracterstica comearam com muito atraso e srio risco de postergao. No entanto, um desenvolvedor de nome Manfred Riem acabou adicionando uma soluo implementao de referncia da especificao JSF (Mojarra) de extrema simplicidade e grande valor, que consiste basicamente nos pontos listados a seguir:

A tag handler para <f:view> agora passa a processar o atributo transient, que j existia em verses anteriores do JSF, passando o valor nela guardado para a raiz da rvore de componentes (UIViewRoot) atravs de uma chamada ao mtodo UIViewRoot#setTransient(boolean transient); Sempre que a raiz da rvore de componentes da view sendo requisitada tiver o seu valor de transincia definido como true (o que passa a ser interpretado como uma view sem estado), a view no ser restaurada. Esta implementao de Manfred, de to simples, limpa e eficaz, foi proposta para padronizao dentro da especificao do JSF. O grupo de trabalho da JSR-344 realizou apenas algumas poucas adaptaes no sentido de acomodar toda a lgica no contexto do framework e, finalmente, lanou o recurso tanto na especificao quanto na implementao de referncia do framework. Naturalmente, h muito espao para melhorias. Atualmente, a propriedade transient deve ser definida como true em cada view que quisermos definir como stateless. A propriedade, no entanto, aplica-se a todos os componentes que constituem uma view, o que pode ser genrico demais em alguns cenrios que desenvolvedores enfrentam no dia a dia. De qualquer forma, o que temos na verso 2.2 j bastante til e interessante, cabendo a ns esperar pela prxima reviso para aproveitar deste recurso de uma maneira mais plena. Concluso Chegamos ao final de nosso estudo sobre o JSF 2.2. Ao longo desta srie de dois artigos, abordamos os principais recursos inseridos nesta nova reviso da especificao, conhecidos como as Big Ticket Features. Neste ltimo artigo, especificamente, comprovamos o quanto se tornou simples trabalhar com alguns recursos muito teis dentro do desenvolvimento web, como o uso dinmico de templates variados, a carga de arquivos e, tambm, o uso de views stateless. Todas essas modificaes passam um recado bastante claro de que no apenas JSF, mas a plataforma Java EE em sua plenitude, vem se tornando cada vez mais completa e, principalmente, aderente ao panorama contemporneo de desenvolvimento de aplicaes web. Desta maneira, figura hoje como um forte candidato a substituir, definitivamente, alguns frameworks que acabaram surgindo exatamente para cobrir deficincias que, por anos, foram marcantes na especificao Java EE. Estes, por no estarem vinculados a um processo to complexo como o proposto pelo JCP, evoluem em um ritmo naturalmente mais acelerado, o que tambm acaba sendo benfico para o ecossistema como um todo, ditando o ritmo do progresso e contribuindo para o alinhamento de pensamentos e o clareamento da ideia por trs de cada demanda da comunidade. Veja, na seo Links, um bom artigo que apresenta uma proposta de substituio do framework Spring por recursos presentes na prpria Java EE, que uma leitura que vem de encontro a isto que acabamos de citar aqui. Falando especificamente de JavaServer Faces, a marcha de seu progresso s no foi mais forte devido, infelizmente, a algumas intempries ocasionadas por todas as notcias veiculadas recentemente sobre vulnerabilidades da tecnologia Java, que mobilizaram boa parte das equipes de engenheiros, desenvolvedores e arquitetos no sentido de acelerar uma resposta frente aos problemas detectados. A resposta, de fato, foi consistente e veio em um intervalo muito curto de tempo, mas trouxe consigo um inevitvel efeito colateral refletido no atraso de alguns dos cronogramas internos. Entretanto, os planos da especificao continuam slidos, e tudo isso nos faz esperar, para uma prxima reviso, solues definitivas para todas as caractersticas que, neste momento, ainda se mostram timidamente, nos limites do que seus escopos, hoje um pouco reduzidos, nos permitem enxergar. Desejamos a todos os leitores um bom divertimento e uma trajetria de muito sucesso e muitos e bons frutos ao adotarem todos esses recursos do JSF 2.2 em seus projetos em Java para a Web.