Início > Programação > Problemas Com o Uso do Partial State Saving no JSF

Problemas Com o Uso do Partial State Saving no JSF

Tive problemas com a restauração do estado de páginas JSF após o request. Entendi que o problema era relacionado à estratégia de otimização da criação de objetos entre requests sucessivos – o State Saving – em escopos de view e a utilização conjunta de tags JSTL. Segue uma explicação da estratégia de gravação e como resolver o problema de restauração de estado.

O que significa Partial State Saving?

Partial State Saving não significa que o estado não será salvo na sessão. Significa apenas que parte da árvore de componentes será salva ao invés da árvore inteira. A idéia é que o estado dos componentes que não serão alterados no cliente em requisições subsequentes não serão salvos.

Ao invés disso, os estados dos objetos são recuperados através da reexecução da view no servidor durante a fase de restauração. Somente os componentes que são sensíveis a mudanças pelo cliente (forms, inputs, buttons, etc) serão salvos.

Para testar, basta alterar o parâmetro boolean do context-param do web.xml a seguir:

<context-param>
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
    <param-value>false</param-value>
</context-param>

Você verá que o consumo de memória aumenta quando o valor é false, o que significa que a árvore de componentes inteira está sendo salva.

Esses objetos são armazenados na sessão porque ela é a única coisa fornecida pela API de Servlet que tem um escopo maior que o da request. Se fossem armazenados na request, os valores se perderiam em request subsequentes. A API de Servlet não tem noção do que significa o view scope do JSF.

Bug na Implementação do Partial State Saving

No Mojarra e provavelmente em outras implementações do JSF há um bug na implementação do Partial State Saving. Ele se manifesta quando se faz o binding de qualquer atributo de um tag handler (JSTL, por exemplo) para um bean com escopo de view. Esses atributos são resolvidos durante a restauração da view.

Com o Partial State Saving ativado, os beans com escopo de view são armazenados no estado parcial da view. Para extrair beans com escopo de view, o estado parcial da view deve ser restaurado (construído) para a view e a EL em todos os atributos deve ser avaliada. Entretanto, como não existe uma instância de bean com escopo de view disponível naquele momento, uma nova instância será criada. Essa nova view terá todas as suas propriedades setadas para o valor default. Após restaurar a view e obter de volta os beans com escopo de view originais, eles serão recolocados no escopo de view, sobrescrevendo temporariamente instâncias criadas durante a restauração da view. Mas as ELs daqueles atributos já foram avaliadas baseado em um instância completamente diferente e não podem ser restauradas.

Como Contornar o Bug do Mojarra

Você pode desabilitar o partial state saving, mas como explicado anteriormente, haverá problemas em performance e uso de memória.

<context-param>
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
    <param-value>false</param-value>
</context-param>

Você poderia também ativar o Full State Saving. Isso permite especificar uma lista dos view IDs cujo partial state saving precisa ser desligado, mas sem alterar o partial state saving dos demais IDs:

    <context-param>
        <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
        <param-value>/some.xhtml,/other.xhtml</param-value>
    </context-param>

Recomendações Para Trabalhar Com JSF Sem Se Preocupar Com os Efeitos Colaterais

Para quase todas as tags JSTL ou JQueryUI, há alternativas nativas do JSF:

01. <c:choose>: usar rendered attribute
02. <c:forEach>: usar <o componente <ui:repeat>
03. <c:if>: usar o atributo rendered
04. <c:set>: usar <ui:param>, <f:viewParam>, @ManagedProperty ou @PostConstruct
05. <f:actionListener>: usar o atributo actionListener
06. <f:convertXxx> (ex.: <f:convertNumber>): usar o atributo converter <f:converter>
07. <f:facet>: não há alternativa. Apenas não use EL em nenhum de seus atributos
08. <f:validateXxx> (ex.: <f:validateLongRange>): usar o atributo validator ou <f:validator>
09. <f:valueChangeListener>: usar o atributo valueChangeListener
10. <ui:decorate>: não há alternativa. Apenas não use EL em nenhum de seus atributo
11. <ui:composition>: não há alternativa. Apenas não use EL em nenhum de seus atributo
12. <ui:include>: usar uma combinação de componentes <ui:fragment rendered> com cada uma dos <ui:include> estáticos
13. qualquer custom tag: deve cumprir JSF UIComponent

Referências

http://stackoverflow.com/questions/10337015/should-partial-state-saving-be-set-to-false
http://stackoverflow.com/questions/4390711/jsf-2-0-partial-state-saving-not-working
http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/#state-saving
http://balusc.blogspot.com.br/2011/09/communication-in-jsf-20.html#ViewScopedFailsInTagHandlers

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: