Diretrizes: Projetando o Estado para Aplicativos J2EE
Tópicos
Introdução

O gerenciamento eficaz do estado do aplicativo é um aspecto importante no design
de aplicativos distribuídos. Essa diretriz fornece uma visão geral de algumas
considerações e mecanismos comuns de design para gerenciamento de estado em um aplicativo J2EE.
As considerações de design relacionadas ao gerenciamento de estado devem ser tratadas durante
a Fase de Elaboração do projeto. O arquiteto de software deve examinar
as abordagens gerais para o gerenciamento de estado como parte das atividades associadas
à Disciplina de Análise & Design Detalhe de
Workflow: Definir uma Sugestão de Arquitetura. Durante a Atividade:
Análise da Arquitetura, o arquiteto de software deve examinar os requisitos de escalabilidade
e desempenho para que o aplicativo determine quais técnicas de gerenciamento de estado
precisarão ser utilizadas para permitir que o aplicativo atenda aos objetivos de
desempenho. À medida que o design do aplicativo é aperfeiçoado durante a
Fase de Elaboração, o arquiteto precisará definir os mecanismos específicos
de design e implementação do J2EE para gerenciar as informações de estado com o
aplicativo na Atividade: Identificar
Mecanismos de Design.
Conforme descrito em Conceitos:
Configurações de Implementação do J2EE, os aplicativos J2EE podem ser compostos de várias
camadas lógicas distribuídas de uma a várias camadas físicas (máquinas).
Após uma breve visão geral técnica do gerenciamento de estado, as seções restantes
dessa diretriz discutirão os diferentes mecanismos de design e implementação do gerenciamento
de estado que podem ser utilizados nas várias camadas de aplicativos.
Observe que o arquiteto de software deve documentar quais mecanismos foram
selecionados como parte do Artefato: Documento
de Arquitetura do Software e deve fornecer diretrizes para a utilização desses mecanismos
como parte das diretrizes de design específicas do projeto.
Visão Geral Técnica

Há uma tendência crescente em se construir aplicativos distribuídos que interajam com
a Internet em um ou outro formulário. Embora os suportes da
Internet sejam por natureza sem preservação de estado, o mais freqüente é a necessidade de gerenciar
o estado para a construção de qualquer tipo de aplicativo de negócios. Considere um aplicativo da Internet
em que um usuário clica em um link da página a para a página b. O aplicativo que está processando
o pedido para a página b não possui mais acesso às informações utilizadas para processar
a página a. Esse comportamento pode ser aceitável para páginas estáticas da Web, mas a maioria
dos aplicativos de negócios requerem algumas informações sobre o processamento anterior.
É aí que entram os mecanismos de gerenciamento de estado fornecidos pelo J2EE.
Estado Transiente versus Persistente
Antes de pesquisar as diretrizes de gerenciamento de estado, é importante diferenciar
entre os tipos de informações de estado. As informações de estado podem ser divididas
em duas categorias: transiente (existe apenas enquanto o aplicativo
estiver ativo) e persistente (existe depois que o aplicativo é finalizado).
As informações do estado transiente existem enquanto a entidade que as contém
estiver ativa. Por exemplo, as informações de estado armazenadas como um campo em uma classe Java
comum. Se o contêiner que hospeda essa classe for finalizado por algum motivo, as
informações de estado serão perdidas, a não ser que os dados tenham sido replicados para outro lugar,
como em um servidor de backup.
O estado persistente existe enquanto existir o data store utilizado para manter as informações
de estado. As informações do estado persistente são armazenadas geralmente em um arquivo ou
banco de dados e são carregadas quando necessário pelo aplicativo. As mudanças às
informações do estado persistente devem ser gravadas de volta no banco de dados. Os
aspectos de integridade e recuperabilidade do data store persistente devem estar
consistentes com aqueles dos dados que estão sendo acessados pelo aplicativo. Um exemplo
de estado persistente são as informações armazenadas em um data store, como um banco de dados
relacional.
Estado de Sessão

Os clientes Web requerem freqüentemente a capacidade de fazer vários pedidos para o navegador, navegando
de página em página, enquanto retêm informações específicas do cliente, como itens,
em um carrinho de compras. Os aplicativos da Web manipulam essa situação criando um ID de sessão e
associando dados de estado a ele. O ID de sessão e o estado associado
são referidos como estado de sessão.
Estado de sessão são dados associados a uma determinada interação do cliente com
um aplicativo da Web durante um curto período de tempo (minutos ou horas, em vez de
dias). Portanto, o estado de sessão são dados de curta duração comumente excluídos depois
de algum período de tempo limite, para evitar o consumo de recursos.
O estado de sessão pode ser armazenado no cliente ou no servidor, conforme descrito em
seções posteriores. A plataforma J2EE fornece mecanismos especificamente adaptados
para gerenciar o estado de sessão, por causa de sua importância em aplicativos com base na Web.
Mecanismos Básicos da Persistência 
A seguir, os mecanismos comuns utilizados por aplicativos da Web para armazenar estado.
Cookies
Cookies são pequenos arquivos de texto armazenados em clientes com base na Web. Um servidor pode armazenar
cookies no cliente. Pedidos subseqüentes do cliente enviam o cookie para o servidor,
fornecendo ao servidor acesso aos dados de estado armazenados no cookie.
Alguns problemas com os cookies:
- Vários usuários acreditam que os cookies comprometem a segurança e/ou privacidade e,
portanto, os desativam.
- Há limites no tamanho de cabeçalhos do cookie, limitando
a quantidade de dados que pode ser armazenada.
- Alguns protocolos, como o WAP (Wireless Access Protocol) não suportam cookies.
- Se um cliente efetuar login a partir de outro local (de outra máquina), os cookies
armazenados no outro local não ficarão disponíveis.
- Os dados de estado devem ser representáveis por valores de cadeia.
Regravação de URL
A regravação de URL é um mecanismo para incorporar o estado de sessão nos URLs referenciados
em cada página. Quando um servidor da Web gera páginas para serem entregues a um cliente,
ele codifica o estado de sessão nos URLs da página. Em seguida, quando o usuário clica
em um URL, os dados de estado nele armazenados são enviados de volta para o servidor, permitindo
o restabelecimento do contexto da sessão. Um mecanismo semelhante utiliza os campos ocultos
do HTML. Alguns problemas com esses mecanismos:
- Todas as páginas de uma determinada sessão devem ser manipuladas pelo servidor, caso contrário, o
servidor pode perder a trilha da sessão.
- O estado não sobrevive quando o cliente encerra seu navegador ou vincula-se
a um URL específico, digitando ou utilizando um marcador.
- Assim como com os cookies, os dados de estado não ficam disponíveis quando o cliente efetua login
a partir de outro local.
- Assim como com os cookies, os dados de estado devem ser representáveis por valores de cadeia.
Arquivo Simples
Um arquivo simples é um dos métodos mais simples de manutenção das informações de estado
persistentes. Na inicialização, o arquivo simples é lido para estabelecer os
valores de estado iniciais. Sempre que o estado é alterado, o arquivo deve ser
regravado para salvar o estado. Algumas desvantagens de se manter
o estado do aplicativo em um arquivo simples são:
- A escalabilidade do aplicativo é afetada adversamente, uma vez que o
aplicativo deve travar o objeto de aplicativo para evitar acesso aos dados
globais enquanto as variáveis do estado do aplicativo estão sendo atualizadas e regravadas no
arquivo simples.
- Na maioria dos casos, a atualização dos dados requererá a regravação do arquivo inteiro.
- Os arquivos simples nem sempre fornecem possibilidade de recuperação no caso de erro.
XML

A manutenção das informações do estado persistente em um arquivo XML é uma etapa ativa em um
arquivo simples. Algumas vantagens de se manter o estado do aplicativo em um arquivo XML,
em oposição a um arquivo simples:
- Um arquivo XML fornece estrutura que não está presente em um arquivo simples.
- Um arquivo XML pode ser analisado utilizando APIs padrão.
- Um arquivo XML é geralmente mais portável.
Banco de Dados

A manutenção de informações de estado persistentes em um banco de dados fornece a máxima
possibilidade de recuperação. Algumas vantagens de se manter o estado do aplicativo em um
banco de dados:
- O design das tabelas fornece estrutura.
- O estado de aplicativo inteiro não precisa ser regravado quando uma
variável do aplicativo é atualizada. Somente as informações atualizadas precisam
ser regravadas.
- É possível manter a consistência coordenando a recuperação do estado do aplicativo
com a recuperação do banco de dados de produção.
- Para situações de alta confiabilidade, o servidor de banco de dados pode ser armazenado em cluster.
Os bancos de dados podem ser acessados utilizando a API do JDBC (Java Database Connectivity) .
O JDBC também pode ser utilizado para acessar outras origens de dados tabulares, incluindo planilhas
e arquivos simples.
Mecanismos Específicos do J2EE 
A plataforma J2EE fornece mecanismos específicos para gerenciar o estado. São
mecanismos de nível superior que podem ser configurados para utilizar um ou mais dos
mecanismos básicos descritos até aqui.
Contexto do Servlet

Os servlets podem utilizar o contexto do servlet para salvar os dados aplicáveis a vários clientes
e sessões de clientes.
Os dados armazenados no contexto do servlet são basicamente variáveis globais para o
aplicativo J2EE. Como resultado, a utilização do estado do aplicativo pode ter um
impacto significativo no design do aplicativo. O arquiteto de software precisa
fatorar nos itens a seguir durante a Atividade:
Identificar Mecanismos de Design para determinar se o contexto do servlet é apropriado:
- O contexto do servlet pode ser mantido em um único processo, portanto, não compartilhado entre
vários servidores (clusters). Se isso não corresponder às necessidades de escalabilidade
do aplicativo, o arquiteto precisará considerar o estado de sessão para armazenamento do estado.
- O contexto do servlet faz parte da memória do processo, portanto, normalmente,
não é mantido quando o processo é finalizado.
- Vários encadeamentos podem acessar os dados globais. O travamento e a sincronização
dos dados globais podem afetar a escalabilidade do aplicativo.
Objeto de Sessão HTTP 
Os servlets e as JSPs podem armazenar os dados associados a uma determinada sessão do cliente
no Objeto de Sessão HTTP. Se os dados forem armazenados em objetos de sessão, é possível que haja
problemas sobre como os dados de sessão serão disponibilizados em vários servidores.
Alguns fornecedores fornecem a capacidade de rotear pedidos do cliente para o mesmo servidor,
uma prática conhecida como "afinidade do servidor".
O Objeto de Sessão HTTP está disponível no servidor durante o processamento de
pedidos do cliente, mas podem ou não ser armazenados no servidor entre os pedidos.
O servidor poderia ser configurável para utilizar qualquer um dos mecanismos básicos de persistência
descritos anteriormente, incluindo o armazenamento do estado de sessão em cookies no
cliente ou em arquivos ou em um banco de dados no servidor. Ele também poderia fornecer a capacidade
de replicar dados de sessão na memória entre os servidores.
O mecanismo é selecionado pela configuração do servidor - as JSPs e os servlets
são codificados independentemente do mecanismo selecionado, acessando o objeto de sessão
por meio de uma API indicada pela especificação Servlet.
Enterprise JavaBeans 
Os Enterprise JavaBeans incluem mecanismos de alto nível para o armazenamento de estado, que
baseiam-se nos mecanismos de nível inferior descritos anteriormente, como bancos de dados
e arquivos. Os beans de sessão com preservação de estado são utilizados para armazenar os dados associados a uma determinada
sessão do cliente, enquanto os beans de entidade são utilizados para armazenar dados de longa duração. Consulte Diretrizes:
EJB para obter uma discussão do estado armazenado pelos EJBs.
Projetando o Estado de Sessão
Os clientes Web requerem freqüentemente a capacidade de fazer vários pedidos para o navegador, navegando
de página em página, enquanto retêm informações específicas do cliente, como itens,
em um carrinho de compras. Os aplicativos da Web manipulam essa situação criando um ID de sessão e
associando dados de estado a ele. O próprio ID de sessão é armazenado no cliente por um ou dois mecanismos:
- cookie - o navegador do cliente envia esse cookie para o servidor em
cada pedido, permitindo que o servidor restabeleça o estado de sessão.
- regravação de URL - os URLs em páginas entregues ao cliente pelo servidor
possuem o ID de sessão codificado. Quando o usuário clica nesse URL, o ID de sessão
é enviado para o servidor, permitindo ao servidor restabelecer o estado de sessão.
O servidor é configurado para utilizar a abordagem selecionada. Os servlets e a JSP devem
ser codificados para funcionarem independentemente do método configurado. Especificamente, utilize o
método HttpServletResponse.encodeURL() para codificar todos os URLs. Esse método verifica
se a regravação de URL está ativada e, se estiver, executa a codificação.
Os dados associados a um ID de sessão podem ser armazenados no objeto de sessão HTTP,
no qual podem ser acessados pelas JSPs e servlets, ou nos beans de sessão.
O ID de sessão e os dados associados devem ser definidos para ter tempo limite, de forma que
os dados de sessão não utilizados por um longo período não consumam recursos
indefinidamente. O arquiteto deve selecionar um período de tempo limite apropriado.
Selecionando o Mecanismo Correto
Os arquitetos devem considerar o armazenamento do estado de sessão no cliente por motivos
de simplicidade e desempenho. Quando o estado é gerenciado e armazenado no cliente,
os servidores não precisam gastar recursos para armazenar informações de estado ou para assegurar
sua consistência. O aspecto negativo do armazenamento de informações de estado com o cliente
é que as informações precisam ser enviadas até o servidor sempre que necessário, portanto,
causando problemas relacionados à latência da rede. Além disso, é possível que haja considerações de segurança,
se houver dados de estado de sessão que você não deseja expor ao cliente.
Nesse caso, a criptografia poderá ser uma opção.
Se o seu aplicativo tiver estado de sessão em excesso, será preferível
armazenar esse estado no servidor, onde geralmente há um tamanho menor e
limitações de tipo.
Geralmente o estado de sessão relacionado a questões de apresentação deve ser armazenado no
objeto de sessão HTTP, enquanto que os beans de sessão com preservação de estado devem conter o estado requerido
para implementar corretamente a lógica de negócios. A duplicação de dados de estado deve
ser evitada - em vez disso, mova os dados de estado duplicados para a sessão HTTP
e os transmita para o bean de sessão como parâmetros nas chamadas de método do bean
de sessão, conforme requerido.
Se os dados de sessão armazenados no servidor sobreviverem à falha de um nó do servidor,
considere a utilização de um mecanismo para persistir ou replicar os dados de sessão.
Projetando o Estado de Longa Duração
Os dados de sessão são para dados do cliente de curta duração que esgotam o tempo limite. É possível que também haja a
necessidade para dados que sobrevivam por períodos de tempo bem mais longos.
O mecanismo correto para esses dados depende da natureza dos dados que estão sendo armazenados.
Cookies, arquivos simples, arquivos XML e bancos de dados representam opções. Para o acesso ao
banco de dados, um bean de entidade é geralmente a melhor opção. Consulte Diretrizes:
Beans de Entidade para obter detalhes.
|