Restaurando View em páginas com auto update

O que aconteceria se o código a baixo estivesse rodando e tivéssemos que fazer um novo deploy no servidor?

xhtml

<h:outputLabel value="#{contadorController.numero}" id="numero">

<p:poll interval="3" listener="#{contadorController.contar}" update="numero" />

Controller

@ManagedBean
@ViewScoped
public class ContadorController implements Serializable {

    private int numero;

    public ContadorController() {
        numero = 0;
    }

    public void contar() {
        numero++;
    }

    public int getNumero() {
        return numero;
    }
}

Se o servidor não for reiniciado, vai ocorrer tudo bem e o contador será chamado a cada 3 segundos.

Agora se o servidor for reiniciado com a página aberta o que aconteceria ? Assim que o servidor voltar o p:poll para uma nova requisição para o controller e receberá uma javax.faces.application.ViewExpiredException: viewId:contador/contador.xhtml – A exibição de contador/contador.xhtml não pôde ser restaurada; porque o contexto do controller foi perdido quando o servidor foi desligado/reiniciado e o que fazer ? Sempre que reiniciar o servidor ir na página e apertar F5 ? Não….é possível criar um filtro para monitorar esse caso e um ViewHandlerWrapper para restaurar o contexto que estava na tela, segue a baixo a implementação:

Criar um filtro que que set um atributo(contadorFilter) na request quando passar pela página contador.xhtml

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class ContadorFilter implements Filter {

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {

 }

 @Override
 public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

          final HttpServletRequest httpRequest = (HttpServletRequest) request;

          // seta o atributo contadorFilter na request
          //apenas para marcar que é uma request na página contador.xhtml
   httpRequest.setAttribute("contadorFilter", Boolean.TRUE);

   chain.doFilter(request, response);

 }

 @Override
 public void destroy() {

 }
}

Mapear o filtro para apenar ser aplicado em /contador/*, pois as outras páginas da aplicação não precisam estar sendo monitoras;

<filter>
  <filter-name>ContadorFilter</filter-name>
      <filter-class>br.com.emmanuelneri.blog.filtros.ContadorFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>ContadorFilter</filter-name>
      <url-pattern>/contador/*</url-pattern>
  </filter-mapping>
</filter>  

As requisições na página contador já estão sendo monitoras, agora é preciso recuperar o contexto quando não houver, que será feito na classe ContadorRestoreViewHandler

import javax.faces.application.ViewHandler;
import javax.faces.application.ViewHandlerWrapper;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

public class ContadorRestoreViewHandler extends ViewHandlerWrapper {
 
private final ViewHandler parent;

 public ContadorRestoreViewHandler(ViewHandler parent) {
  this.parent = parent;
 }

 @Override
 public ViewHandler getWrapped() {
  return parent;
 }

 @Override
 public UIViewRoot restoreView(FacesContext context, String viewId) {
                
                // restaura a View com o contexto e viewId atual
  UIViewRoot root = super.restoreView(context, viewId);
                 
                // caso a restauração for nula e tenha o atributo 
                // contadorFilter na request

                // cria uma nova View para o context e viewId atual
  if (root == null && ((HttpServletRequest) context.getExternalContext().getRequest()).getAttribute("contadorFilter") != null) {
   root = createView(context, viewId);
  }

  return root;
 }
}

Declara o ContadorRestoreViewHandler no faces.config

<application>
    <view-handler>br.com.emmanuelneri.blog.filtros.ContadorRestoreViewHandler</view-handle>
</application>

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 )

Foto do Google+

Você está comentando utilizando sua conta Google+. 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 )

w

Conectando a %s