Começando com JSF 2.4 e Primefaces 12

29/09/2020 por Professor Danilo

Começando com JSF 2.4 e Primefaces 12

Em meados dos anos 90 surgiu a tecnologia que revolucionou o mundo, a Internet. A internet possibilitou a comunicação, publicidade, comércio, lazer, conhecimento e infinitas possibilidades de uso da tecnologia. Seu sucesso no Brasil se iniciou em 1995 e neste ano a internet tinha cerca de 120 mil usuários usando conexões discadas pela linha telefônica. Em 1998 o país já contava com cerca de 2,1 milhões de usuários.

Com o sucesso emitente da internet muita tecnologia foi desenvolvida. O desenvolvimento web nos primórdios da internet era ainda rudimentar, páginas web contavam com recursos simples e em 1994 o CSS estava iniciando sua jornada. Mas de 25 anos depois a internet se tornou uma ferramenta poderosa praticamente indispensável no mundo atual.

Junto com a evolução da internet podemos dizer que inúmeras ferramentas e tecnologias surgiram para deixar a internet mais dinâmica e amigável a todos.

Dentre tantas ferramentas, a linguagem Java apresentou suas primeiras ferramentas em 1999 com o JavaServer Pages (JSP), similar ao PHP, que usava container servlet para entregar as páginas. A importância de uma linguagem de programação para Web era a capacidade de tornar dinâmica as páginas, isto é, o conteúdo mudava de acordo com o banco de dados por exemplo.

Em 2004 é lançada as especificações do JavaServer Faces (JSF 1.0), Ao longo deste 16 anos diversas atualizações foram feitas e diversas críticas ao JSF foram criadas. Apesar das críticas, trabalhar com JSF ainda é realidade e diversas empresas ainda fazem uso da ferramenta. Hoje com a versão 2.3, o JSF recebeu diversas melhorias e sua forte integração com o diversos frameworks Java, faz com que a ferramenta se torne algo interessante diante de tanto framework Javascript.

Conhecendo o Maven

No desenvolvimento com Java utilizamos soluções também que simplificam o empacotamento das classes e gestões das bibliotecas externas, para isto o projeto será criado usando o Maven. Com o Maven configurado no projeto, as bibliotecas ficam declaradas no arquivo pom.xml que fica localizado na pasta raiz do projeto. Por ser um arquivo xml, somente texto é declarado fazendo com que o uso das libs externas não sejam carregadas junto ao projeto deixando seu tamanho muitas vezes menor.

O Maven possui uma central própria (https://repo.maven.apache.org/maven2) onde a maioria das libs já estão disponibilizadas. Quando seu projeto é compilado pelo Maven, as bibliotecas necessárias são baixadas para a pasta .m2/repository no diretório do usuário, no windows por exemplo ficaria: C:\Users\Danilo\.m2\repository, já no linux fica: /home/danilo/.m2/repository. No linux todo arquivo ou diretório iniciado com ponto deixa os mesmos ocultos, na maioria dos gestores de arquivo a telca de atalho para mostrar os arquivos ocultos é Control + h.

Para compilar o projeto é necessário internet, contudo somente a primeira vez, pois o Maven baixa as dependências e as coloca na pasta “.m2” não sendo mais necessário a internet, isto faz com que a primeira execução do Maven demore muito para finalizar, mas é normal, nas próximas vezes não haverá mais este tempo de espera.

Dica: se sua conexão com internet não é muito boa e você precisar formatar a máquina, você pode copiar a pasta “.m2” e depois cola-lá novamente no mesmo lugar, assim as dependências não precisarão ser baixadas da internet.

O repositório central do Maven pode não suprir tudo, neste sentido você pode usar repositórios de terceiros ou até mesmo criar um servidor com seu próprio repositório. Empresas que não querem expor certas bibliotecas acabam por criar servidores internos para disponibilizar suas bibliotecas com os desenvolvedores, assim não expõe as libs na internet.

O código abaixo apresenta a estrutura principal do Maven, sendo que o groupId é composto por um identificador da sua organização, sendo mais comum o uso do domínio invertido assim como nos pacotes Java. Como exemplo o domínio professordanilo.com.br foi utilizado para formar o groupId. Logo após o groupId temos o artifactId, ele é responsável por identificar o artefato (projeto) dentro da sua empresa. É importante que projetos tenham nomes diferentes para não gerar conflitos. Uma vez que identificamos o groupId e o artefatoId, agora chegou a hora de dividir um artefato. O artefato é dividido em versões com a tag version. Para saber mais sobre o Maven acesse a documentação oficial que leia as diretrizes do pom.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>br.com.professordanilo</groupId>
    <artifactId>comecando-com-jsf</artifactId>
    <version>1.0</version>

</project>

Para a maioria dos projetos Java ainda precisamos de mais algumas tags especificadas pelo Maven sendo elas:

  • <packaging>…</packaging> – Diz para o Maven como deverá ser empacotado o código compilado. Os pacotes comuns são: pomjarmaven-pluginejbwarearrar.
  • – Onde será declarada uma lista com as dependências que o projeto terá.
    • – Uma dependência individual.
      • <groupId>org.glassfish</groupId>
      • <artifactId>javax.faces<artifactId>
      • <version>2.3.9</version>
  • – O build é usado para configurações específicas de como será compilado o projeto. O build faz uso de de plugins para organizar o processo de construção.
    • – Onde são configurados os plugins que serão utilizados.
      • <plugin> … </plugin> – Onde de fato é declarado o plugin a ser utilizado.

As tags acima são apenas uma pequena parte do que o Maven pode oferecer, inúmeras outras tags estão disponíveis e podem ser consultadas na documentação oficial.

Criando o projeto web no Netbeans

Ao utilizar uma IDE, em geral elas otimizam a criação dos projetos já gerando um arquivo POM necessário. Para esta artigo faremos uso do Netbeans para demonstrar a criação de um projeto web com JSF. A versão utilizada do Netbeans é a 12.1.

Uma vez que seu Netbeans está aberto, você deverá acessar o menu Arquivo (File) > Novo (New) > Java Com Maven (Java With Maven) > Aplicação Web (Web Application). Uma tela similar a tela abaixo aparecerá.

Criando um projeto Web com Maven no Netbeans 12.1

Dica: Caso a versão do seu Netbeans seja o 8.2, você deverá descer até a categoria Maven antes de selecionar a Aplicação Web.

Na tela do Netbeans é possível perceber que o nome do projeto é utilizado automaticamente como nome do artefato esta mesma tela podemos deixar configurado o GroupId, Version e Package. O Package é utilizado para definir a estrutura de pacotes Java.

Ao avançar pelo botão Próximo (Next) será necessário escolher o servidor web. Usaremos o Tomcat, no entanto algumas versão do Tomcat se apresentaram instáveis em nossos testes relacionado a execução do Tomcat pelo Netbeans. A partir da versão 8.5 o Netbeans não consegue executar corretamente o Tomcat não executando a aplicação criada, por isto optamos por utilizar a versão 8.0.53 do Tomcat podendo ser baixada aqui. Para mais informações acesse a página oficial do Tomcat.

Seleção do Servidor

Selecionado o servidor e clicado em Terminar (Finish) o Maven entrará em ação para baixar dependências do Java e Java Web (Caso não tenha criado nenhum projeto com Maven ainda) e ao final deverá mostrar que o projeto foi construído com sucesso (Build Success) e também aparecerá na aba projetos.

Projeto construído com sucesso.

Neste ponto estamos prontos para começar a conectar as dependências que teremos no nosso projeto e realizar as configurações para que nosso projeto com JSF comece a funcionar.

Configurando o projeto Web do Netbeans

Para desenvolver com JSF precisamos de três coisas principais, o Java Web na lib “javaee-web-api“, a lib do JSF “javax.faces” e a injeção de dependências “cdi-api“.

O Java EE Web API é configurado automaticamente pelo Netbeans na versão 7.0 no momento da criação do projeto, mas você pode mudar para uma versão mais recente se quiser. Abaixo a dependência do Java WEB no Maven configurada pelo Netbeans:

<dependency>
       <groupId>javax</groupId>
       <artifactId>javaee-web-api</artifactId>
       <version>7.0</version>
       <scope>provided</scope>
</dependency>

Troque por:
<dependency>
       <groupId>javax</groupId>
       <artifactId>javaee-web-api</artifactId>
       <version>8.0.1</version>
       <scope>provided</scope>
</dependency>

Além do Java Web, também será necessário configurar a dependência do JSF implementado pela Mojarra. Servidor como o Glassfish já possuí a dependência embutida sendo necessário configurar uma dependência diferente, no entanto como vamos utilizar o Tomcat será necessário configurar conforme as linhas abaixo. Dica: Você pode colocar a lib no Tomcat, assim não precisará compilá-la junto ao projeto, no entanto para nosso exemplo tudo será compilado junto ao projeto.

<dependency>
       <groupId>org.glassfish</groupId>
       <artifactId>javax.faces</artifactId>
       <version>2.4.0</version>
</dependency>

O JSF 2.3 utiliza as especificações de injeção de dependência do CDI, a partir desta versão o uso do CDI se tornou obrigatório, com isto precisamos de um container capaz de gerenciar as dependências do JSF. Para utilizar um servidor mais simples e barata como Tomcat é necessitará de configurar o Weld CDI que é uma implementação das especificações do do Java CDI.

Para usar o Weld com JSF será necessário importar 3 libs do próprio Weld.

<dependency>
       <groupId>org.jboss.weld</groupId>
       <artifactId>weld-core</artifactId>
       <version>2.4.8.Final</version>
</dependency>
        
<dependency>
       <groupId>org.jboss.weld</groupId>
       <artifactId>weld-core-jsf</artifactId>
       <version>2.4.8.Final</version>
</dependency>

<dependency>
       <groupId>org.jboss.weld.servlet</groupId>
       <artifactId>weld-servlet</artifactId>
       <version>2.4.8.Final</version>
</dependency>

Uma vez que estas dependências estiverem configuradas nosso arquivo pom.xml ficará assim:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>br.com.professordanilo</groupId>
    <artifactId>comecando-com-jsf</artifactId>
    <version>1.0</version>
    <packaging>war</packaging>

    <name>comecando-com-jsf</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    <dependencies>
        
        <dependency>
            <groupId>org.jboss.weld</groupId>
            <artifactId>weld-core</artifactId>
            <version>2.4.8.Final</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.weld</groupId>
            <artifactId>weld-core-jsf</artifactId>
            <version>2.4.8.Final</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.weld.servlet</groupId>
            <artifactId>weld-servlet</artifactId>
            <version>2.4.8.Final</version>
        </dependency>
        
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.faces</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>8.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>7.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

A TAG <properties> e a TAG <build> foram geradas pelo próprio Netbeans. A TAG <properties> uma forma de definir variáveis e reaproveitá-las no documento. A TAG <build> é responsável por configurar como o Maven deverá compilar o projeto. Através do Plugin maven-compiler-plugin é configurado a forma como será compilado os arquivos Java. O plugin maven-war-plugin informará o empacotamento que deverá ser feito, no início do documento também é possível ver o <packaging>war</packaging> informando o tipo da saída do arquivo final.

Atualização: Nas versões mais novas o Maven está gerando erro ao compilar com o “maven-war-plugin” na versão “2.3”, troque a versão para 3.3.2. Troque também o source e target para “1.8”. Com isto o projeto deverá rodar perfeitamente.

Finalizando a configuração do projeto

Para finalizar o projeto há mais três tarefas a serem feitas:

A primeira é com relação a criação de uma página do JSF. Quando o Netbeans cria um projeto web ele cria junto um arquivo HTML simples, para o JSF precisamos criar uma página .xhtml ou .jsp, o XTHML é a forma mais atual de trabalhar e a que usaremos na criação a ser feita. Na aba Projetos (Projects) deverá conter uma pasta com nome Páginas da Web (Web Pages) e dentro dela haverá uma pasta META-INF e um arquivo index.html. O arquivo index.html poderá ser apagado pois não será utilizado. Com a pasta Páginas da Web selecionada você deverá acessar o Menu Arquivo > Novo Arquivo, selecionar a Categoria JavaServer Faces e selecionar Página JSF (JSF Page).

Criação de Páginas no JSF

Conforme a tela abaixo, o nome do arquivo deverá ser informado e o tipo do arquivo poderá ser modificado, a recomendação é trabalhar com o formato Facelets, desta forma um arquivo index.xhtml será criado na pasta webapp (Páginas da Web), você pode conferir o caminho completo onde será criado o arquivo.

Criando Página JSF.

Ao criar o arquivo index.xhtml a primeira tarefa está concluída e o conteúdo da página provavelmente estará assim:

<?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>Facelet Title</title>
    </h:head>
    <h:body>
        Hello from Facelets
    </h:body>
</html>

É possível perceber TAGs que não fazem parte do HTML convencional como o <h:head> e <h:body>, estas TAGs são processadas pelo JSF e ao final o que o navegador irá renderizar será de fato <head> e <body>.

A segunda tarefa a ser feita é configurar o arquivo web.xml na pasta WEB-INF, este arquivo não existia, ao criar um arquivo do JSF o Netbeans verifica que não existe um arquivo de configuração web e o cria automaticamente. O arquivo web.xml terá o seguinte código:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" 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-app_3_1.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

No parâmetro javax.faces.PROJECT_STAGE é automaticamente configurado Development, esta configuração diz ao JSF qual é o estágio do projeto aceitando Development e Production, a diferença é que no estágio de desenvolvimento algumas erros e avisos destinados ao programador poderão aparecer, enquanto em produção estes erros e avisos não aparecem.

No Faces Servlet – javax.faces.webapp.FacesServlet é configurado um servlet que ficará escutando as requisições feitas ao servidor e entregará as páginas JSF solicitadas. Esta configuração caminha junto com o servlet-mapping com o nome Faces Servlet, nele é indicado o url-pattern que indica ao JSF qual padrão de URL ele deverá ficar escutando. Neste url-patter está configurado /faces/*, ou seja, qualquer requisição que chegar ao servidor com /faces/algumas-coias, será interpretado pelo JSF e ele tentará localizar a página correspondente. No entanto costumamos *.xhtml, assim qualquer página endereço com a extensão informada será localizada.

Ao mudar o utl-pattern do JSF é necessário também mudar o welcome-file, por padrão é configurado faces/index.xhtml, como não será mais utilizado o /faces/ então apenas removemos ele do endereço ficando apenas index.xhtml.

Neste ponto finalizamos a segunda tarefa de configuração do projeto, nosso arquivo web.xml ficará assim:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" 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-app_3_1.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

Dúvidas sobre outras configurações deste arquivo poderão ser esclarecidas nos comentários abaixo.

Para finalizarmos a última tarefa de configuração, precisaremos criar um arquivo de configuração do CDI, este arquivo diz respeito a quais classes o CDI deverá vasculhar no projeto para construir a injeção de dependência. No Netbeans este arquivo também pode ser facilmente criado no Menu Arquivo > Novo Arquivo na categoria Context and Dependency Injection e selecionando o tipo de arquivo beans.xml (CDI configuration file). Neste ponto recomendamos criar o arquivo sem modificar nada pois o padrão do CDI conseguirá localizar corretamente o arquivo, caso contrário deverá ser modificado o a localização padrão.

Arquivo de configuração do CDI – beans.xml.

Este arquivo será criado na pasta WEB-INF junto ao arquivo web.xml e deverá ser feita uma pequena alteração para que tudo funcione como desejado. O seguinte código deverá constar no arquivo:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       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/beans_1_1.xsd"
       bean-discovery-mode="annotated">
</beans>

Ao final das propriedades da TAG beans tem este código bean-discovery-mode=”annotated”, ele diz ao CDI quais classes deverão ser verificadas e gerenciadas. Em nosso caso trocaremos o valor annotated para all, assim ele vasculhará todo nosso projeto e verificará todas as classes. Em projetos maiores outras estratégias deverão ser tomadas pois com muitos arquivos o projeto poderá também consumir muita memória, mas para nosso exemplo será mas fácil usar esta abordagem. Ao final o arquivo ficará da seguinte maneira:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       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/beans_1_1.xsd"
       bean-discovery-mode="all">
</beans>

Finalização e teste

Para que possamos testar o real funcionamento do JSF, uma classe Java deverá ser criada, para isto criamos uma classe com nome TesteBean no pacote bean (um pacote padrão para este tipo de classe).

A classe criada deverá ter uma anotação @Named, esta anotação informa ao CDI e ao JSF que é uma classe gerenciada, desta forma uma página JSF consegue chamar um código Java.

A anotação @SessionScoped diz como o servidor deverá controlar a classe, no caso desta anotação o servidor mantém a classe na memória durante toda a sessão. A sessão é configurada no arquivo web.xml, se voltar ao arquivo verá que o tempo pré-configurado é de 30 e este tempo é relativo a minutos, esta sessão só expira (encerra) quando o navegador que acessou e gerou a sessão ficar mais que 30 minutos sem acessar novamente o servidor. Caso haja um acesso no minuto 29 a contagem então é reiniciada e mais 30 minutos deverão ser aguardados para que os arquivos na memória relativos a sessão sejam eliminados.

Por último para que o CDI possa criar e gerenciar nossa classe TesteBean ela deverá implementar Serializable. O Serializable do pacote java.io diz respeito a capacidade de pegar esta classe da memória e gravar seu estado em disco, isto é, colocar da memória RAM no HD a instância da classe TesteBean sem alterar nada e voltá-la para a memória quando necessário (uma forma de cache). Praticamente todas as classes relacionadas com CDI devem implementar Serializable.

package br.com.professordanilo.comecandocomjsf.bean;

import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;

@Named
@SessionScoped
public class TesteBean implements Serializable {

    private String hello = "Olá mundo";
    
    public String getHello() {
        return hello;
    }
        
}

Para verificarmos o funcionamento da classe TesteBean criamos um atributo de classe com o nome de hello e um método getHello para expor a variável para fora da classe, desta forma agora podemos colocar esta variável na página index.xhtml.

Para que um valor seja exibido no nosso xhtml ou seja enviado do xhtml para a classe Java é necessário usar um recurso conhecido por Expression Language (EL). Uma EL é composta por # e chaves {}. Dentro da EL passamos o nome da classe e em seguida o atributo ao qual queremos usar. Através de uma EL podemos acessar atributos e métodos. No nosso exemplo iremos exibir o atributo hello, no entanto o atributo é private no Java por isto foi necessário criar um método getHello do tipo public. Uma EL consegue interpretar os atributos mesmo sendo private, para pegarmos o valor do hello escrevemos a EL assim:

#{testeBean.hello}

Não foi preciso usar getHello, a EL tenta pegar o nome hello e procura na classe testeBean por get + hello colocando a primeira letra do nome em maiúscula. Desta forma atributos podem ser facilmente encapsulados sem a necessidade de chamar os respectivos métodos. Caso não exista um método get para o atributo solicitado, o EL verifica se existe o atributo public, então podemos (se assim desejar) criar um atributo public sem a necessidade de métodos get (NÃO RECOMENDADO).

Vale notar que o nome da classe TesteBean começa com letra maiúscula, no entanto quando estamos usando a EL o nome da classe é diferente da instância da classe. Este nome pode ser personalizado na anotação @Named(value = “teste”), desta forma ao invés de usar testeBean poderia simplesmente usar teste. De qualquer forma não é comum ficarmos mudando o nome da classe já que por padrão (quando não informado) o nome da instância é o nome da classe com a primeira letra minúscula.

Nossa página index.xhtml ficará assim:

<?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>Facelet Title</title>
    </h:head>
    <h:body>
        #{testeBean.hello}
    </h:body>
</html>

Para executar o projeto no Netbeans no menu Executar (Run) > Limpar e Construir (Clean and Build). Esta ação faz com o que o Maven exclua os arquivos compilados (Limpar) e compile novamente (Construir). Este mesmo atalho se encontra na barra de botões.

Limpar e construir no Netbeans.

Se tudo que você fez até aqui está correto a seguinte página deverá aparecer no seu navegador:

Resultado da execução do projeto.

Para encerrar…

Não podíamos encerrar sem falar no Primefaces. O Primefaces é uma biblioteca de User Interface desenvolvida pela PrimeTek focada em trazer componentes opensource para o JSF. Apesar de ter começado com JSF hoje a equipe do primefaces desenvolvem componentes para JSF, Angular, React e Vue. O Primefaces é rico em componentes, desde a componentes simples de entrada de textos até componentes completos como tabelas e gráficos. A documentação do Primefaces conta com um showcase que exibe uma Demo dos componentes em funcionamento além de apresentar também de forma simples o código necessário para começar com o componente. Em alguns casos o showcase é tão completo que a documentação acaba ficando um pouco de lado.

Para usarmos o Primefaces precisamos apenas importar sua dependência. Na página de downloads existe uma versão paga chamada de Pró e Elite, estas versões chegam mais rápido aos desenvolvedores e empresas, mas a versão para a comunidade é livre.

<dependency>
       <groupId>org.primefaces</groupId>
       <artifactId>primefaces</artifactId>
       <version>12.0.0</version>
</dependency>

A dependência do Primefaces está disponível na central do Maven e uma vez adicionada no arquivo pom.xml basta Limpar e Construir o projeto para que seja baixada e esteja disponível para uso.

Modificando mais uma vez a página index.xhtml, agora precisamos importar as tags do Primefaces, para isto basta inserir na tag html o namespace: xmlns:p=”http://primefaces.org/ui”. A letra p logo após o xmlns define um prefixo para os componentes, assim se quiser usar um inputText para escrever <p:inputText>. No exemplo abaixo colocamos um componente panel com um header “Hello Primefaces” e dentro dele um componente de inputText com nosso #{testeBean.hello} no atributo value. Ficando assim nosso xhtml:

<?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:p="http://primefaces.org/ui">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <p:panel header="Hello Primefaces">
            <p:inputText value="#{testeBean.hello}"></p:inputText>
        </p:panel>       
    </h:body>
</html>

O resultado final foi este:

Visualização do resultado final com Primefaces.

Conclusão

JSF ainda é uma ferramente completa para desenvolvimento, com sua integração forte com o Java e vários frameworks torna se uma peça poderosa de produtividade para desenvolvimento web. Com frameworks como Primefaces o desenvolvimento pode ser acelerado principalmente usando todo ferramental que a empresa PrimeTek fornece e preocupa em manter atualizado.

Assim como Java não é a única linguagem, JSF não é o único framework para desenvolvimento web, cada projeto tem sua particularidade e esta sim deve ser considerada a risca para que o objetivo final seja entregar um software funcional e com qualidade.

Faltou algo que não falei comente abaixo e vamos trocar uma ideia.

14 Comentários

  1. excelente tutorial, atualizado
    Infelizmente, no meu netbeans o browser não é acionado Nenhum workaround até agora resolveu.

      1. professor, obrigado pela inesperada atenção
        FAIL – Deployed application at context path /myapp but context failed to start
        Já procurei e testei um monte de workaround, creio que seja algo do meu ambiente
        Sem org.jboss.weld ele volta a abrir o html, mas com eles ocorre o erro mencionado

          1. Mais uma vez obrigado pela atenção.
            Fica como registro e aprendizado. Em um dos muitos foruns li uma observação que me chamou a atenção e resolveu o problema. Mudei o logon do serviço do tomcat para um conta local. Era problema de permissão de escrita. Quando o tomcat instaciava a aplicação, não conseguia escrever um arquivo XML (context acho) no /user/nomeuser/appdata/local

  2. Excelente post.

    Sou desenvolvedor java e gosto muito ainda do primefaces e do jsf, apesar de hoje em dia ele ter perdido espaço para frameworks mais modernos como react por exemplo.

    Acho que se ele for usado corretamente se torna muito produtivo ainda mais se no projeto java web for integrado o spring data jpa, eu integrei ele em um projeto java ee e a produtividade subiu muito.

    Vale citar que a combinação de jsf 2.3 e primefaces 8 é excelente.

    O primefaces 8 possui novos componentes para manipulação de datas, totalmente implementados pensando na versão 8 do java com a api de datas joda time.

    Na data de hoje o primefaces já está na versão 10 e os exemplos demonstrados e na sua página já estão todos codificados na versão 8 do java.

    1. Excelente colocação, apesar de ver muita gente criticando a tecnologia, o propósito ao qual foi criado funciona, no entanto o JSF é muito fácil fazer implementações de forma incorreta pelas facilidades que ele dá.

      Com relação ao Primefaces 8 tivemos muitas atualizações importantes, o Primefaces 10 deu um salto a mias trazendo ainda mais componentes e refinamentos. Acredito muito na produtividade do Java e em breve vou lançar no Youtube um curso completo de JSF com Primefaces.

  3. Muito bom o tutorial, eu gosto bastante do JSF. Obvio que o JSFcomo muito bem colocado por você em um comentário acima, é uma tecnologia de nicho, ela serve para alguns tipos de aplicação mas sejamos sinceros, a maioria das aplicações desenvolvidas por ai não são um iFood,Facebook, CartolaFc,Netflix,etc… a maioria doque é desenvolvido são aplicações de controle de fluxo de caixa, controle de estoque, sistemas de escritórios de contabilidade, advocacia,cartórios,etc… e o JSF se encaixa muito bem em todos esses tipos de aplicação, adicionar um desses frameworks javascript com uma rest api pra esse tipo de aplicação é adicionar uma complexidade desnecessária. É preciso ter cuidado com esses Gurus de tecnoogias, as vezes a intenção é apenas vender livros, cursos,etc…

    1. Concordo, JSF é uma tecnologia muito específica, mas não é conhecimento desperdiçado já que se pode migrar para Spring e trabalhar com REST para integração com outros frameworks e tecnologias.

  4. Boa tarde.
    ocorre o mesmo erro (“FAIL – Deployed application at context path /myapp but context failed to start”), relatado pelo usuário André.
    Alguma solução?

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *