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,
pode-se diminuir o consumo de banda com a compactação do estado dos componentes antes de enviar ao cliente (método client);
pode-se melhorar a segurança da aplicação encriptando o estado dos componentes antes de enviar ao cliente (método client);
pode-se também diminuir o consumo de memória no lado servidor através de configurações mais detalhadas da framework, utilizando-se de frameworks como Spring-annotation, JBoss-Seam e até componentes como t:saveState do Myfaces-Tomahawk que nos fornecem “escopos” para mantermos os dados entre requests;
pode-se corrigir o problema do back-button do browser aumentando o número de views por sessão (método server);
etc
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 :))
Share this:
Twitter
Facebook
Curtir isso:
Curtir Carregando...
Relacionado
Categorias:Java, JavaScript, JEE, Jsf, webTags:back button, client, Java, JavaServer Faces, JBoss, JEE, Jsf, method, performance, Seam, server, state saving, state saving method, STATE_SAVING_METHOD, t:saveState, web
Publicado por Rafael Ponte
Engenheiro de Software na Zup Innovation tentando ajudar outro(a)s dev(a)s e times a performarem melhor através da educação. Nas horas vagas um podcaster frustrado no @DevsCansados.	Ver todos os posts por Rafael Ponte	
Navegação de posts
Previous Post Previous post:javasf – JavaServer Faces International Group
Next Post Presença confirmada no III Natal Java Day
27 Replies to “STATE_SAVING_METHOD – server ou client ?”	
Ivan Carlos says: 14 anos atrás
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.
Jullierme Barros says: 14 anos atrás
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!
Handerson Frota says: 14 anos atrás
Boa rafael ;D belo post, ta indo bem 😀
CMilfont says: 14 anos atrás
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.
Vladymir says: 14 anos atrás
Parabéns irmone. Muito foda.
Um dia chego lá.
kk
abraço
Pingback: Utilizando AJAX com JSF de maneira eficiente | Rafael Ponte
Rubem Azenha says: 14 anos atrás
Só agora vi o post e achei muito bem explicado 🙂 Parabéns 🙂
Maria Fernanda Correa says: 13 anos atrás
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.
Sérgio Fantin says: 13 anos atrás
Matou a pau!
Paulo Fernandes says: 13 anos atrás
Rafael, estou iniciando na área e tendo muito dos problemas que posta em seu blog…
um dia espero saber um pouco do que voc~e sabe….
parabéns pelo Blog.
abraço
Gabriel Cardelli says: 11 anos atrás
Excelente Post.
Fernando Boaglio says: 11 anos atrás
Boa explicação, parabéns Rafael.
Sávio says: 11 anos atrás
Parabéns .Bem explicado. Muito bom o post.
Julio P. Leiser says: 11 anos atrás
Muito bem explicado o post, ajudou em muito.
Pingback: [JSF] ViewExpiredException – Como solucionar? « iDeIAS
Pingback: Problema do rendered dinâmico com JSF | Rafael Ponte
Fabiano says: 11 anos atrás
Há como tratar o problema de sessionExpired utilizando o STATE_SAVING_METHOD servidor?
Rafael Ponte says: 11 anos atrás
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).
Douglas Hiura says: 10 anos atrás
Muito bom…
Everton says: 10 anos atrás
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?
Douglas says: 9 anos atrás
Ótimo Post Valeu..
Bem didático e me ajudou muito.
Leandro Machado says: 8 anos atrás
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.
Ed Pichler says: 7 anos atrás
Pesquiso sobre javax.faces.STATE_SAVING_METHOD no Google e me deparo com tu nos primeiros resultados, o jovem Rafael Ponte do Jafasf hehehe legal
Alberto says: 7 anos atrás
Boa tarde Rafael, tudo bem?
Estava passando pelo problema de back-button, ai a solução que implementei por hora foi , sinceramente, achei ruim toda vez que retornar tenho que ficar dando F5 na página, lendo seu artigo vi que poderia utilizar o método client, mas em conversa com o pessoal da infra eu passei as questões levantadas acima e não concordaram muito, preferem ter o custo no servidor mesmo.
Segundo o que eu entendi lendo seu artigo é que dá para resolver aumentando o número de views per session.
Eu setei o parâmetro numberOfViewsInSession para 30/50 e não surtiu efeito.
Se me permite o exemplo que eu tenho é:
Minha tela parte de uma listagem;
Clico no botão criar;
Clico em backspace;
Vou tentar editar algum item da lista ele não edita, é como se não chamasse mais nenhum método do managed bean, só se eu der um F5 ou entrar na tela novamente.
Poderia me ajudar por favor?
Obs.: Eu utilizo como base um projeto que você disponibilizou, se não me engano o título é maneira eficaz com JSF, Primefaces e Spring.
Alberto says: 7 anos atrás
Rafael desculpa acho que coloquei o link errado no post anterior.
Fabio Souza says: 6 anos atrás
Meu caro Rafael, bela postagem, agradecer aqui ao Manoel Neto por indicar esse texto que pra mim como novato no mundo do JSF, foi bem esclarecedor! Grande abraço!