A sincronização e segurança de atributos em Servlets
Antes de iniciar o artigo, é recomendável ter um certo conhecimento em servlets e sessões.
Sabe-se que as sessões são únicas para cada cliente. Ou seja, não há como clientes de diferentes fontes interferirem em atributos presentes no escopo de sua sessão. Há também o fato de que mesmo os servlets podendo acessar os atributos destas sessões em outras threads, uma solicitação é uma thread única o que reforça mais a ilusão de que seu atributos estão seguros.
Na verdade há situações em que mais de uma solicitação por parte do cliente ocorre simultaneamente. É o caso, por exemplo, do mesmo abrir uma nova aba (ou janela) enquanto a anterior é carregada e diferentes solicitações serem enviadas.
Por mais que a possibilidade citada seja improvável, nunca é demais cuidar da segurança dos atributos envolvidos em uma aplicação web; principalmente quando se tratam de grandes empresas que possuam lojas online, serviços que envolvam cartões de crédito ou outros dados importantes e que devam ser encapsulados o quanto for necessário para que se mantenha a confiança do cliente.
Em casos como este muitas vezes se recorre a idéia de sincronizar o método responsável pela execução da aplicação, com mostra a Listagem 1.
public synchronized void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
//códigos adicionais por parte do programador
//exemplo de adição/alteração de atributos
HttpSession session = req.getSession();
session.setAttribute(“nome do atributo”, “valor”);
}
Listagem 01
A ação de sincronizar um método de serviço, além de não permitir mais o processamento simultâneo não protegerá os atributos da sessão. Em se tratando de atributos de contexto, por exemplo, apenas uma thread do mesmo servlet, porderá acessar o método em um momento, mas não impede de outros servlets acessarem.
O que realmente irá proteger de apenas uma thread (independemente de onde ela vier) acessar o atributo é sincronizando o próprio objeto no código, como mostra a listagem 02.
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
//códigos adicionais por parte do programador
//exemplo de adição/alteração de atributos
HttpSession session = req.getSession();
synchronized(session){
session.setAttribute(“nome do atributo”, “valor”);
}
}
Listagem 02
Ao invés de sincronizar o acesso ao método, sincronizou-se apenas o acesso ao objeto que irá cuidar de adicionar ou alterar o atributo. Fazendo isso, o fluxo da aplicação será apenas interrompido no momento em que for necessário.
É necessário frisar que em todos os trechos de código onde há chamadas a setAttribute (para o exemplo atual), se o bloco synchronized(session) não encapsulá-los, de nada adiantará. Logo, deve-se sincronizar o objeto session durante toda a aplicação.
Concluindo, a sincronização afeta o processamento simultâneo de uma aplicação, é verdade. Mas quando se trata de segurança é o mínimo que se pode fazer para evitar transtornos e perda de tempo reescrevendo código. Em casos como este, sincronizar o menor trecho de código possível é o mais recomendável, visto que o fluxo será interrompido rapidamente.
Um grande abraço e até a próxima.
* para criação do artigo, foi utilizado como base o livro: Use a Cabeça! Servlets & JSP; Brian Basham, Kathy Sierra & Bert Bates.