STATE_SAVING_METHOD – server ou client ?

Uma das dúvidas mais frequentes na lista de discussão do javasf está relacionado em como o JSF mantém o estado da árvore de componentes de uma view, qual a diferença e qual deve-se usar: client ou server? Acredito que a melhor maneira de responder a estas perguntas está em saber a diferença entre os dois métodos, e é exatamente isso que pretendo explanar mais abaixo..

A framework nos fornece dois métodos para mantermos o estado da árvore de componentes, os métodos são “client” e “server”, ou seja, é possível manter o estado dos componentes no cliente (página gerada) ou servidor (session).

Mas o que diacho é esse “estado da árvore de componentes”? Bem, no JSF os dados são armazenados em dois caminhos diferentes: dentro do escopo de beans e dentro da árvore de componentes. O escopo de beans(managed-beans) por si só é auto-explicativo. Já o escopo da árvore de componentes é onde estão armazenados os dados(estados) destes componentes, eles são armazenados no response e então são recuperados quando um request chega, com isso o JSF consegue manter o estado de cada componente inalterado até que se mude para uma nova página.

No método “client” o estado da árvore será persistido no cliente, para ser mais exacto ele será serializado e encodado na base64 e ficará em um campo do tipo HTML-input-hidden na página gerada para o cliente(browser). Já no método “server” o estado será persistido na sessão do usuário, ou seja, no servidor e não mais no cliente. Cada um possui suas vantagens e desvantagens, veremos isso mais a frente..

Você poderá facilmente definir qual método pretende usar inserindo no web.xml da sua aplicação o seguinte trecho de código:

<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>

No código acima o param-value poderá ser definido como server ou client, por default o método é o server. Bem, depois de definido qual método usar e re-startar a aplicação começaremos a sentir as diferenças.

Diferenças

Método server

  • há um maior consumo de memória no lado servidor pois o estado esta sendo mantido na sessão por usuário;
  • problemas com o back-button do browser (é necessário mais consumo de memória para resolver este problema);
  • baixo consumo de banda na rede;
  • baixo consumo de memória no cliente;
  • uso de cpu no servidor é baixo;
  • clustering – mover a sessão para um outro nó do cluster (muitos dados na sessão);
  • melhora comunição via AJAX pois não é preciso reenviar o estado da view ao servidor;
  • páginas carregam mais rapidamente (ou pode-se dizer normalmente?);

Método client

  • menos uso da session e consequentemente menos consumo de memória no lado servidor;
  • sem consumo de memória entre requests;
  • corrige problemas de refresh (tecla F5) e botão voltar (back button) do browser;
  • resolve problemas de concorrência;
  • melhora escalabilidade da aplicação;
  • alto consumo de banda da rede;
  • maior overhead de cpu no servidor e cliente;
  • maior consumo de memória no lado cliente;
  • problemas de segurança;
  • excelente na fase de desenvolvimento pois conseguimos manter o estado da view mesmo depois de restartar o servidor;
  • páginas carregam ligeiramente mais lentas (isso depende muito da complexidade e quantidade de componentes na página);

* Os itens em vermelho indicam as desvantagens

Cada um traz consigo melhorias e problemas em determinados pontos, em alguns pontos há efeito contrário de acordo com o método escolhido, ou seja, se no método “server” algo funciona então pode ser que no método “client” pare de funcionar, e vice-versa. A maioria destes problemas podem ser resolvidos durante o desenvolvimento com algumas boas práticas, configurações, frameworks auxiliares e até truques, como por exemplo,

Estes são apenas alguns exemplos de como contornar tais problemas, algumas soluções o JSF já nos fornece com algumas configurações mais específicas, outras necessitaremos de frameworks auxiliares. No final das contas conseguimos contorna-los sem muitas dificuldades.

Então, qual devo usar?

Como podem ver há várias diferenças entre eles, mas dizer qual o melhor método é algo que vai depender muito do tipo de aplicação, quantidade de usuários e acessos, se é intranet ou não, entre outros detalhes do projeto. O ideal é conhecer a diferença entre eles e analisar qual método se encaixa melhor nos requisitos e necessidades do projeto.

Boa parte deste texto foi baseado nas discussões da lista javasf, leituras em blogs, fóruns, wikis, e principalmente nesta excelente apresentação, http://wiki.apache.org/myfaces-data/attachments/Performance/attachments/PerformanceBOFatJavaOne

Espero que esse texto sirva de alguma ajuda aos novatos na tecnologia e até alguns veteranos :))

25 thoughts on “STATE_SAVING_METHOD – server ou client ?

  1. Meus parabéns Rafael, vc está escrevendo muito bem. As observações que tinha que fazer sobre o texto já te fiz, continue assim, sucesso.

  2. Boa Ponte….

    Agora com um blog hein hehehe, muito bom….

    Não deixe de nos avisar sempre que postar algo …..

    Muito interessante este post, parabéns!

  3. Não é querendo ser reclamão não, mas precisamos de artigos básicos que comecem explicando o início, tipo, o que é árvores de componentes antes de saber o que é estado das ditas :)
    Faça um post ai sobre o ciclo de vida esse tipo de coisa.

  4. Muito bom seu post!

    Ressalvo o que foi dito em relação ao t:saveState, pois ele resolve problema de usar duas listas (selectManyListBox), na qual qualquer alteração que é feita em outra página, ao voltar para as listas, os dados não eram atualizados.
    Quando eu tive esse problema fiquei dias procurando na internet até descobrir que o saveState (com o bean request) resolveria meu problema.

  5. Olá Fabiano,

    O STATE_SAVING_METHOD como “server” se utiliza do escopo de sessão do usuário, logo se o escopo expirar então todas as árvores de componentes cacheadas também irão expirar e provavelmente poderá ocorrer o ViewExpiredException. Já no modo “client” é mais dificil acontecer, mesmo após a sessão ter expirado, contudo pode-se configurar um timeout e o erro pode ser disparado.

    Para evita-lo o que você pode fazer é configurar seu web.xml para redirecionar para uma página de erro (ou mesmo de login) quando o erro ocorrer, é o meio mais simples que conheço. Aqui tem um exemplo, https://github.com/rponte/jsf-loja-project/blob/master/WebContent/WEB-INF/web.xml#L128

    Ou, muitas vezes um Servlet Filter pode resolver, pois antes de cair no Servlet do Faces o filtro já barra a requisição por estar validando a sessão do usuário (algo como verificar se o usuário está logado ou não).

  6. Rafael, eu tenho um menu que é composto por commandLinks, quando eu clico em um menu(commandLink) tenho uma função javaScript para mudar a cor do menu. Porem no mesmo click ele chama outra pagina pois realiza um post na tela. Como faço pra manter o estado do meu commandButton colorido?

  7. Rafael, parabéns pelo post.

    Acredito que irá me ajudar a resolver um problema na aplicação que usa o valor server no parâmetro do STATE_SAVING_METHOD. Ajudou muito a entender a diferença entre client e server e qual utilizar para o projeto. Pelo visto, depende de aplicação para aplicação qual o valor a ser utilizado no projeto para receber as requisições do usuário.

    Obrigado e novamente parabéns.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>