Quando usar , arquivos de tags, componentes compostos e / ou componentes personalizados?

Eu comecei a usar o JSF 2.0 com o Facelets recentemente e fiquei intrigado com novos componentes compostos conhecendo as e outras técnicas de modelagem oferecidas pelo Facelets 1.x.

Qual é a diferença entre essas abordagens? Funcionalmente, eles parecem oferecer o mesmo: vs , + arquivos de tags vs, reutilização dos modelos existentes. Existe alguma coisa além de syntax e especificação de interface clara no caso de componentes compostos? O desempenho pode diferir?

Qual é a diferença entre essas abordagens?

Modelos de facelet

Use modelos do Facelet (como em , e ) se você quiser dividir os fragments do layout da página principal em modelos reutilizáveis. Por exemplo, header, menu, conteúdo, rodapé, etc.

Exemplos:

  • Como include outro XHTML em XHTML usando JSF 2.0 Facelets?
  • Qual é a diferença conceitual real entre ui: decorate e ui: include?
  • Como personalizar o h: head ao usar o ui: template de composição?
  • Como alterar os elementos principais de uma página ao usar o ui: composition
  • Como ajax-refresh dynamic include content pelo menu de navegação? (JSF SPA)

Arquivos de tag Facelet

Use os arquivos de tags do Facelet se você quiser ter um grupo reutilizável de componentes para evitar / minimizar a duplicação de código. Por exemplo, um grupo de componentes label + input + message. A principal diferença entre os componentes compostos é que a saída de um arquivo de tags do Facelet não representa um único UIComponent e pode, em algumas circunstâncias, ser a única solução quando um componente composto não é suficiente. Geralmente, ter um com um ou mais é um sinal de que o arquivo de inclusão pode ser melhor um arquivo de tags.

Exemplos:

  • Como criar uma tag personalizada do Facelets?
  • Como fazer uma grade de componente composto JSF?
  • Como criar um componente composto para uma coluna de dados?
  • Primefaces outputLabel para componente composto

Componentes compostos

Use componentes compostos se você quiser criar um UIComponent personalizado único e reutilizável com uma única responsabilidade usando XML puro. Esse componente composto geralmente consiste em um monte de componentes existentes e / ou HTML e é renderizado fisicamente como um único componente e deve estar vinculado a uma única propriedade de bean. Por exemplo, um componente que representa uma única propriedade java.util.Date por 3 componentes , ou um componente que combina e em um único referindo-se a um único entidade personalizada com.example.Image como propriedade.

Exemplos:

  • Nossa página wiki Componente composto
  • O código BalusC: componente composto com vários campos de input
  • Split java.util.Date em dois campos h: inputText representando hora e minuto com f: convertDateTime
  • Selecione todos os itens em Multiple SelectManyCheckBox com ids dynamics
  • Estendendo o componente JSF commandLink
  • Evitando IDs duplicados ao reutilizar composições de facelets no mesmo contêiner de nomeação

Componentes personalizados

Use um componente personalizado sempre que a funcionalidade não puder ser obtida com arquivos de tag Facelet ou componentes compostos, devido à falta de suporte no conjunto de componentes padrão / disponível. Exemplos podem ser encontrados em todo lugar no código-fonte de bibliotecas de componentes de software livre , como PrimeFaces e OmniFaces .

Manipuladores de tags

Quando você quiser controlar a construção da tree de componentes JSF em vez de renderizar a saída HTML, use um manipulador de marcas em vez de um componente.

Exemplos:

  • Componente Custom Facelet no JSF
  • Como posso acessar o conteúdo de algo criado com programaticamente?
  • Renderização condicional no tagfile, dependendo se o atributo é especificado ou não
  • Execução de um redirecionamento quando a conversão / validação associada a parâmetros de consulta falhar

Projetos de exemplo

Aqui estão alguns exemplos de projetos que utilizam todas as técnicas acima mencionadas.

  • Aplicativo de lançamento do Java EE ( templates – includes – tagfiles – composite )
  • OmniFaces Showcase ( modelos – inclui – tagfiles – compostos )

O desempenho pode diferir?

Tecnicamente, a preocupação com o desempenho é insignificante. A escolha deve ser feita com base nos requisitos funcionais concretos e no grau final de abstração, reutilização e sustentabilidade da implementação. Cada abordagem tem seu próprio propósito e limitações bem definidos.

Os componentes compostos, no entanto, têm uma sobrecarga significativa durante a criação / restauração da exibição (especificamente: durante o salvamento / restauração do estado de exibição). E, em versões mais antigas do Mojarra, componentes compostos tiveram problemas de desempenho com a atribuição de valores padrão, isso já está corrigido desde 2.1.13. Além disso, Mojarra tinha um memory leaks quando uma é usada para expressões de método, basicamente toda a tree de componentes é re-referenciada na session HTTP, isso é fixo desde 2.1.29 / 2.2.8. O memory leaks pode ser ignorado nas versões 2.1 mais antigas, conforme abaixo:

  com.sun.faces.serializeServerState true  

Ou em versões mais antigas 2.2 como abaixo:

  javax.faces.SERIALIZE_SERVER_STATE true  

Ainda assim, quando você tiver relativamente “muitos” componentes compostos e tiver javax.faces.STATE_SAVING_METHOD definido como client , o desempenho será penoso. Não abuse de componentes compostos se você quiser apenas a funcionalidade básica que já é possível com um simples arquivo de inclusão ou arquivo de tags. Não use a facilidade de configuração (leia-se: nenhum arquivo *.taglib.xml necessário) como uma desculpa para preferir componentes compostos sobre arquivos de tags.

Ao usar o Mojarra 2.2.10 ou mais antigo, não se esqueça de desativar o período de atualização relativamente curto do Facelets para o modo de produção:

  javax.faces.FACELETS_REFRESH_PERIOD -1  

Não use essa configuração para desenvolvimento, caso contrário, você terá que reiniciar o servidor inteiro para que as alterações nos arquivos do Facelets sejam refletidas! Mojarra 2.2.11 e mais novo, e MyFaces já é padronizado para -1 quando javax.faces.PROJECT_STAGE não está definido como Development .

Intereting Posts