Skip to content

JSF (Jakarta Faces)

Definição: JSF (JavaServer Faces)

JSF, hoje Jakarta Faces, é o framework web baseado em componentes da plataforma Java EE/Jakarta EE. Em vez de escrever HTML e tratar requisições, você monta a tela com componentes (h:inputText, h:dataTable) ligados a objetos Java (os managed beans), e o JSF cuida do ciclo de requisição, da conversão, da validação e da renderização.

Ainda é muito usado em sistemas corporativos brasileiros (geralmente com PrimeFaces), por isso aparece em vagas e em manutenção de legado. O pacote mudou de javax.faces para jakarta.faces (Jakarta EE 9+); os conceitos são os mesmos. Para o acesso a dados, veja Acesso a dados com Java; para a visão geral de MVC, Arquiteturas de código.

Do servlet ao framework baseado em componentes

Etapa Ideia Problema
Servlets Código Java trata a requisição HTTP e escreve o HTML HTML misturado ao Java
JSP HTML com trechos Java Lógica volta a se misturar à página
MVC por ações (Struts, Spring MVC, VRaptor) Controlador recebe a requisição, processa e escolhe a view O framework não conhece a tela, só a requisição
MVC por componentes (JSF, Wicket) O framework constrói e mantém a árvore de componentes da tela Curva de aprendizagem; entender o ciclo de vida é obrigatório

Nos frameworks baseados em ações, você pensa em requisições e respostas; no JSF, pensa em componentes, eventos e estado, parecido com programação desktop.

Anatomia de uma tela

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="jakarta.faces.html" xmlns:f="jakarta.faces.core" xmlns:ui="jakarta.faces.facelets">
<h:body>
  <h:form>
    <h:panelGrid columns="2">
      <h:outputLabel for="marca" value="Marca"/>
      <h:inputText id="marca" value="#{automovelBean.automovel.marca}" required="true"/>
      <h:outputLabel for="ano" value="Ano"/>
      <h:inputText id="ano" value="#{automovelBean.automovel.ano}">
        <f:validateLongRange minimum="1950" maximum="2030"/>
      </h:inputText>
    </h:panelGrid>
    <h:commandButton value="Salvar" action="#{automovelBean.salvar}"/>
    <h:messages/>
  </h:form>
</h:body>
</html>
  • Telas são Facelets (arquivos .xhtml). Os namespaces importam as bibliotecas de tags: h: (componentes HTML), f: (núcleo: conversores, validadores, Ajax) e ui: (templates).
  • Expression Language (EL): #{automovelBean.salvar} liga a tela ao managed bean (hoje, um bean CDI com @Named). Na leitura, o JSF chama o getter; no envio, o setter; em ações, chama o método.
  • Managed bean guarda o estado da tela e trata as ações; devolve um outcome (texto) para a navegação (ou void para ficar na mesma tela).
  • Componentes principais: h:inputText, h:inputTextarea, h:selectOneMenu, h:selectOneRadio, h:selectManyCheckbox, h:dataTable (com facets para cabeçalho/rodapé e classes CSS por linha), h:commandButton/h:commandLink (ações), h:outputText, h:graphicImage, h:panelGrid (layout em colunas) e rendered para exibição condicional.
  • O clique não chama o método diretamente: o navegador envia um formulário (POST) e o JSF percorre o ciclo de vida abaixo.

Ciclo de vida do JSF

Entendê-lo é "entender como o JSF funciona". Cada requisição passa por seis fases:

flowchart LR
    A[1. Restore View<br/>cria ou recupera a árvore de componentes] --> B[2. Apply Request Values<br/>copia os valores enviados para os componentes]
    B --> C[3. Process Validations<br/>converte e valida]
    C --> D[4. Update Model Values<br/>atualiza o managed bean]
    D --> E[5. Invoke Application<br/>executa a ação do bean]
    E --> F[6. Render Response<br/>gera o HTML]
    C -. erro de conversão/validação .-> F
  • Na primeira requisição a árvore de componentes é criada; nas seguintes, recuperada (o estado fica na sessão ou no cliente: view state).
  • Se a conversão ou a validação falhar, o JSF pula para a renderização, não atualiza o modelo e não executa a ação: um erro clássico para quem acha que "o método não foi chamado".
  • PhaseListener é como um Filter, mas notificado antes e depois de cada fase (útil para log, medição, transações).
  • Os renderizadores convertem cada componente em HTML; bibliotecas como PrimeFaces e RichFaces trazem componentes e renderizadores próprios.

Conversão, validação e mensagens

  • Conversores: transformam String em objeto e o inverso. Já existem para tipos básicos (Integer, Date...); crie um Converter para entidades (por exemplo, um <h:selectOneMenu> cujos itens são objetos Marca, e não ids). f:convertDateTime e f:convertNumber formatam datas e números conforme o locale.
  • Validadores: required, f:validateLength, f:validateLongRange, f:validateRegex (ex.: login de 6 a 18 minúsculas), validadores customizados e Bean Validation (@NotNull, @Min... na entidade), que o JPA também aplica ao gravar; é possível agrupar restrições (grupos) e criar validações próprias, como "ano máximo = ano atual + 1".
  • Mensagens: h:messages (todas) e h:message for="id" (por componente), com requiredMessage, converterMessage e validatorMessage. Use label nos componentes e arquivos de propriedades (messages.properties) para internacionalização; sem label, a mensagem mostra o id gerado, pouco útil.
  • A ação devolve um outcome (texto); o JSF procura uma regra de navegação no faces-config.xml ou aplica a navegação implícita (JSF 2): o outcome vira o nome da página no mesmo diretório. Retornar void/null mantém a mesma tela.
  • URLs favoritáveis (bookmarkable): f:metadata + f:viewParam leem parâmetros da URL (?id=10) e f:viewAction carrega os dados ao abrir a página. h:link/h:button geram links GET; h:commandLink faz POST.
  • Para evitar reenvio de formulário ao dar F5, use redirect após POST (?faces-redirect=true).

Escopos dos managed beans

Escopo Dura Quando usar
Request (@RequestScoped) Uma requisição Dados simples; cuidado com combos dependentes: ao perder o estado, o item selecionado é inválido
View (@ViewScoped) Enquanto o usuário permanece na mesma tela Formulários e tabelas com Ajax (o mais usado)
Conversation (@ConversationScoped) Uma sequência de telas Assistentes e edições em várias etapas
Session (@SessionScoped) Sessão do usuário Usuário logado, preferências; evite guardar muito
Application (@ApplicationScoped) Toda a aplicação Caches de dados comuns (estados, municípios)

Beans de sessão e de aplicação são compartilhados: cuide da concorrência.

Ajax, templates e componentes compostos

  • Ajax: <f:ajax event="change" execute="@this" render="modelos mensagens"/> envia parte do formulário (execute) e atualiza partes da tela (render) sem recarregar. Exemplo clássico: combos em cascata (escolher a marca atualiza a lista de modelos).
  • Templates (Facelets): ui:composition/ui:insert/ui:define fixam o que raramente muda (topo, menu, rodapé) e definem só o conteúdo de cada página; ui:include inclui fragmentos e ui:param passa parâmetros.
  • Composite components: componentes reutilizáveis montados em XHTML (cc:interface, cc:implementation, cc.attrs, cc:insertChildren), por exemplo "campo com rótulo + mensagem de erro", eliminando repetição. Ficam na pasta resources, a mesma usada para CSS, JavaScript e imagens (carregamento padronizado com h:outputStylesheet, h:outputScript, h:graphicImage).

JSF com JPA: cuidados e desempenho

  • EntityManager por requisição: o tempo de vida curto da requisição combina com o do EntityManager (padrão Open EntityManager in View, JPA e ORM), evitando LazyInitializationException ao renderizar associações.
  • N+1 no h:dataTable: se cada linha acessa uma associação lazy, o JSF dispara uma consulta por linha. Corrija com JOIN FETCH ou projeções (N+1).
  • Não faça consultas dentro de getters: eles são chamados várias vezes por requisição (uma por fase e por componente). Carregue os dados em um método de ação/@PostConstruct e guarde em atributo.
  • Caches da JPA: o de primeiro nível (por EntityManager) é automático; o de segundo nível (@Cacheable, compartilhado entre requisições, com EhCache/Infinispan) e o cache de consultas (com @QueryHint) reduzem leituras, mas exigem invalidação e atenção à consistência (dados desatualizados).
  • Paginação de listagens grandes (lazy data model do PrimeFaces), tamanho do view state e imagens como recursos (não como byte[] em cada requisição) melhoram a escalabilidade.
  • Ferramenta: ative as estatísticas da implementação de JPA (Hibernate) e registre-as por um Filter ou PhaseListener para achar consultas lentas.

JSF hoje: quando usar

Pontos fortes: produtividade para telas CRUD corporativas, conjunto grande de componentes (PrimeFaces), validação e conversão integradas, integração com CDI, Bean Validation e JPA. Pontos fracos: estado no servidor (escala exige cuidado), curva de aprendizado do ciclo de vida, menos popular que SPAs para interfaces ricas. Para APIs e front-ends modernos, veja Spring e Angular.

Para responder em entrevista

Pergunta Ideias para a resposta
"O que é JSF e como difere do Spring MVC?" Baseado em componentes (estado e eventos) x baseado em ações (requisição/resposta); JSF mantém árvore de componentes
"Explique o ciclo de vida do JSF." Seis fases; erro de conversão/validação pula para a renderização sem executar a ação
"Por que meu método de ação não foi chamado?" Falhou conversão/validação, ou o componente está fora do h:form, ou campo required vazio
"Qual escopo usar?" @ViewScoped para telas com Ajax; @RequestScoped para o simples; sessão com parcimônia
"Como evitar N+1 em uma tabela?" JOIN FETCH/projeção, consulta única carregada na ação; não consultar em getters
"O que são composite components e templates?" Reuso de partes de tela: templates para layout, componentes compostos para widgets repetidos