JSF 2 – visão geral e novidades do framework
A versão 2 do Java Server Faces é significativamente melhor do que a versão 1 em vários aspectos. Trazendo, sobretudo, conceitos que foram incluídos anteriormente no JBoss Seam, a nova especificação possui inúmeras vantagens que facilitam a vida do desenvolvedor.
Vamos a um levantamento delas:
Mudanças do Core do JSF
- Anotações nas classes substituíram várias entradas no faces-config.xml. Exemplos:
- Managed Bean: @ManagedBean. Exemplo:
Antes (jsf 1.x):<managed-bean> <managed-bean-name>carroBean</managed-bean-name> <managed-bean-class>br.com.projeto.bean.CarroBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>
Agora (jsf 2):
@ManagedBean public class CarroBean { }
- Converter: @FacesConverter. Exemplo:
Antes (jsf 1.x):
<converter> <converter-id>converter.ConversorDeCpf</converter-id> <converter-class>br.com.projeto.converter.ConversorDeCpf</converter-class> </converter>
Agora (jsf 2):
@FacesConverter("converter.conversorDeCpf") public class ConversorDeCpf implements Converter { }
- Validator: @FacesValidator. Exemplo:
Antes (jsf 1.x):
<validator> <validator-id>validator.validadorDeCpf</validator-id> <validator-class>br.uece.projeto.validator.ValidadorDeCpf</validator-class> </validator>
Agora (jsf 2):
@FacesValidator("validator.validadorDeCpf") public class ValidadorDeCpf implements Validator { }
- Podem ser usados nomes default. Por exemplo: se a classe que possui a anotação @ManagedBean se chama pacote1.pacote2.MeuBean, você pode usar #{meuBean.atributo} no código;
- O escopo view foi adicionado. A ideia é manter determinados dados enquanto o usuário não mudar de tela. As instâncias dos managed beans em escopo view são eliminadas somente quando há uma navegação entre telas;
- Managed Beans possuem escopo request por padrão
- Para especificar escopo use @RequestScoped, @ViewScoped, @SessionScoped e @ApplicationScoped nos Managed Beans.
- Por padrão, a instância de um managed bean em escopo application é criada no momento em que ela é usada pela primeira vez. Podemos alterar esse comportamento, fazendo com que essa instância seja criada quando a aplicação é inicializada. Basta acrescentar a propriedade eager com o valor true na anotação @ManagedBean;
- Novos botões <h:button /> e <h:link /> realizam requisições HTTP do tipo GET. As URLs das requisições são geradas pelo JSF a partir do atributo outcome. Não devem ser utilizados para submissão de formulários;
- Novo componente <h:outputFormat />. Permite diversos tipos de formatação do texto que será exibido. Exemplo:
<h:outputFormat value="Preço do carro {0}: R$ {1}"> <f:param value="#{carroBean.carro.nome}"/> <f:param value="#{carroBean.carro.preco}"/> </h:outputFormat>
- Podemos alterar o comportamento padrão do JSF, fazendo com que ele considere o conteúdo de uma caixa de texto não preenchida como null. Esse comportamento é obtido acrescentando o seguinte trecho no arquivo web.xml:
<context-param> <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name> <param-value>true</param-value> </context-param>
- Para padronizar a organização dos recursos da sua aplicação e facilitar a internacionalização, o JSF 2 permite a criação de bibliotecas de imagens e o uso das novas tags <h:outputScript /> e <h:outputStylesheet />:
- A criação de uma biblioteca de imagens é simples: adicione um diretório na pasta /resources (na raiz da aplicação). Por exemplo, se criarmos o diretório /resources/carros/ e adicionarmos a imagem golf.png nesse diretório, podemos inseri-la em uma página da seguinte forma:
<h:graphicImage library="carros" name="golf.png" />
- As tags <h:outputScript /> e <h:outputStylesheet /> devem ser usadas com a notação:
<h:outputScript name="mascara-carro-brasil.js" library="javascript" target="head" /> <h:outputStylesheet name="estilo-carro-brasil.css" library="css" />
- Suporte integrado a facelets
- JSF 2 despreza o JSP como linguagem da camada de visão;
- Possibilidade de utilizar bookmarking;
- Suporte nativo a Ajax;
- Suporte nativo a Groovy;
- Mais detalhes no debug
- Colocando o valor Development na configuração javax.faces.PROJECT_STAGE do web.xml, aparecerão mensagens de erro mais explícitas que antes não eram disparadas na versão 1.x. Exemplo:
<context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param>
- Não é mais necessário usar regra de navegação (navigation-rule) no faces.config.xml. Basta que o nome da página corresponda à string retornada pela action ou pelo componente;
- Exemplo: se a sua página se chama formulario.xhtml e ela está na raiz do conteúdo web, você pode redirecionar para formulario.jsf;
- Podemos criar navegações condicionais. Imagine uma aplicação em que os usuários podem escolher o idioma que desejam utilizar. As regras de navegação podem então considerar essa situação através da tag na definição de uma regra de navegação. Veja o exemplo:
<navigation-rule> <from-view-id>/login.xhtml</from-view-id> <navigation-case> <from-outcome>sucesso</from-outcome> <if>#{usuarioBean.idioma[’preferencia’] == ’pt-BR’}</if> <to-view-id>/home-brasil.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>sucesso</from-outcome> <if> #{usuarioBean.idioma[’preferencia’] == ’en-US’}</if> <to-view-id>/home-internacional.xhtml</to-view-id> </navigation-case> </navigation-rule>
- Você pode usar #{meuBean.meuAtributo} diretamente na página ao invés de <h:outputText value=”#{meuBean.meuAtributo}” />;
- Está mais simples desenvolver componentes. Agora a programação deles está baseada no facelets e não no próprio java, como era antes;
- Uma nova abordagem para definir validações. A ideia é declarar as regras de validação nas classes do modelo através de anotações ao invés de inseri-las nos arquivos XHTML que definem as telas. O recurso usado foi o Bean Validation, especificado na JSR 303. As opções são:
Anotação | Utilidade | Chave no Arquivo properties |
@AssertTrue | Verifica se uma propriedade booleana possui valor false. | {javax.validation.constraints.AssertTrue.message} |
@AssertFalse | Verifica se uma propriedade booleana possui valor true. | {javax.validation.constraints.AssertFalse.message} |
@DecimalMax | Define o valor real máximo que uma propriedade pode armazenar. | {javax.validation.constraints.DecimalMax.message} |
@DecimalMin | Define o valor real mínimo que uma propriedade pode assumir. | {javax.validation.constraints.DecimalMin.message} |
@Digits | Define a quantidade máxima de dígitos da parte inteira (através do atributo integer) ou da parte fracionária (através do atributo fraction) de um número. | {javax.validation.constraints.Digits.message} |
@Future | Verifica se uma data é posterior ao instante atual. | {javax.validation.constraints.Future.message} |
@Max | Define o valor inteiro máximo que uma propriedade pode assumir. | {javax.validation.constraints.Max.message} |
@Min | Define o valor inteiro mínimo que uma propriedade pode assumir. | {javax.validation.constraints.Min.message} |
@NotNull | Verifica se o valor de uma propriedade não é null. | {javax.validation.constraints.NotNull.message} |
@Null | Verifica se o valor de uma propriedade é null.v | {javax.validation.constraints.Null.message} |
@Past | Verifica se uma data é anterior ao instante atual. | {javax.validation.constraints.Past.message} |
@Pattern | Verifica se o valor de uma propriedade respeita uma expressão regular. | {javax.validation.constraints.Pattern.message} |
@Size | Define os tamanhos mínimo (através do atributo min) e máximo (através do atributo max) para uma Collection, array ou String. | {javax.validation.constraints.Size.message} |
Tabela 1: anotações do Bean Validator.
- É possível desabilitar a validação de uma propriedade com anotação em uma ou mais telas específicas com a tag <f:validateBean> e o atributo disable com o valor true. Exemplo:
<h:inputText value="#{carroBean.carro.nome}"> <f:validateBean disabled="true" /> </h:inputText>
- As mensagens do bean validation podem ser personalizadas. Exemplo: @NotNull (message =”O nome não pode ser nulo “)
- Nesse caso estamos usando uma mensagem fixa, não dando suporte para internacionalização;
- Também é possível mapear a mensagem da annotation a uma chave de um arquivo resource-bundle. Exemplo: @NotNull(message=”{br.com.projeto.funcionario.nome}”)
- Essa solução é recomendada quando queremos usar uma mensagem personalizada e a chave deve ser inserida em um arquivo chamado ValidationMessages.properties, que deve ser colocado no classpath da aplicação;
- Outra opção é alterar as mensagens padrões dos validadores do bean validation. Nesse caso não precisamos usar o atributo message da Annotation. Basta usar as chaves que estão na tabela 1 publicada no mesmo arquivo comentado no item anterior.
Mudanças do Facelets
- Suas páginas devem terminar com .xhtml;
- Use <h:head>, <h:body> e <h:form>;
- Em geral, não é necessário usar mais <f:view>;
Referências:
http://www.coreservlets.com/JSF-Tutorial/jsf2/
http://www.jboss.org/richfaces
Desenvolvimento Web com JSF2 e JPA. Download gratuito em http://www.k19.com.br/downloads/apostilas-java/k19-k12-desenvolvimento-web-com-jsf2-e-jpa2
Java Server Faces 2 & Rich Faces 4 – Novidades e Alterações. Disponível em http://brunovasconcelos.wordpress.com/2012/04/10/jsf-2-rich-faces-4-novidades/
Agradecimento:
Bruno Garcia Vasconcelos – http://brunovasconcelos.wordpress.com/
Quer saber as mudanças do RichFaces 4? Clique aqui e veja meu post abordando as mudanças e melhorias.
Porque não usar mais o f:view
?
Grande amigo Marcus Mazzo. Segundo os tutoriais do site Core Servlets (que são baseados no cursos de treinamento do Marty Hall, autor do livro Core Servlets and Java Server Pages), geralmente não se deve mais usar o ‘f:view’. Você encontra a fonte de onde extrai nesse endereço: http://www.coreservlets.com/JSF-Tutorial/jsf2/#New-Features. Talvez a frase esteja mal formulada. Vou modificar. Abraço.
Blz, outra coisa que não entendi… no trecho “Mudanças do Facelets” você diz para usar e mas porque isso visto que H é a taglib HTML do JSF? Não entendi onde isso entra no Facelets?
Fala Marcão. Cara, as tags h:body e h:head são novas, portanto antes tínhamos que usar outra opção. Já h:form coloquei porque não existe mais a4j:form. Como muitas vezes usamos essas tags no template, decidi colocar no facelets, mas você tem razão, encaixa melhor na parte de JSF. Abraço.
Não apareceu o h:form h:head e h:body na mensagem anterior 😛
Olá, parabens pelo post mas por que “Não use mais ‘f:view'” ?
é algo específico do RF4? eu sei que o Primefaces não funciona sem ‘f:view’ em web-kit browsers como Chrome e opera.
Fala Rafael. A mesma resposta do Marcus Mazzo. Segundo os tutoriais do site Core Servlets (que são baseados no cursos de treinamento do Marty Hall, autor do livro Core Servlets and Java Server Pages), geralmente não se deve mais usar o ‘f:view’. Você encontra a fonte de onde extrai nesse endereço: http://www.coreservlets.com/JSF-Tutorial/jsf2/#New-Features. Talvez a frase esteja mal formulada. Vou modificar. Abraço.
Meu Caro Pablo com sempre muito bom , só gostaria de ênfatizar o Managed Beans com +1 opção de escopo : ViewScoped.Parabens.
Maurício, acho que você quis dizer @NoneScoped ou @CustomScoped, não? Decidi não abordar nenhum dos dois porque o @NoneScoped é pouco usado e o @CustomScoped, pelas referências que tive é muito complicado de usar. abraço
Criei o arquivo ValidationMessages.properties e coloquei no Resources do meu projeto, mas não funciona, ele exibe a chave ao invés do valor da mesma, tem alguma ideia do que pode ser?
Obrigado
José, sua dúvida não está relacionada a JSF 2, mas acho que posso ajudar. O problema deve ser porque você não colocou o valor entre chaves. Deve ficar assim: message=”{erro.salvar.entidade}”. Outro possível erro é que a especificação Bean Validation não deve estar encontrando o arquivo properties. Já experimentou colocá-lo dentro da raiz da pasta source?