Quantcast
Channel: Marcos Sousa's Blog » Jboss Seam
Viewing all articles
Browse latest Browse all 10

FacesContext em Seam Remoting calls

$
0
0

Faz um tempinho que não escrevo nada por aqui. Além de projetos críticos que estou participando, estava muito envolvido na leitura de dois livros relacionados a Agile, que os comentarei em breve, e também estou escrevendo uma série de artigos para a revista Java Magazine, o primeiro sai na edição 72. A partir de agora devo publicar pelo menos uns 2 post mensais. ;)

O Seam Remoting oferece uma forma conveniente de acessar componentes backing beans via AJAX. Com uma simples anotação é possível chamar ações, intanciar objeto e etc. Porém este recurso é uma maneira limitada de acessar o contexto dos componentes e requer uma certa atenção de nós desenvolvedores. Pessoalmente, pude presenciar soluções fantásticas usando remoting e mas algumas implementações desastrosas. Fica a dica: use o remoting apenas quando os componentes AJAX existentes não solucionam um dado problema.

Por padrão, uma requisição AJAX via Seam Remoting não possui controle de transações e o contexto JSF não é criado. Para ambos os casos é possível habilitá-los. O controle de transações é mais simples, basta adicionar a anotação @Transactional com o tipo REQUIRED. Veja o exemplo:

@WebRemote @Transactional(TransactionPropagationType.REQUIRED)
public void updateUserProfile(Profile profile) {
entityManager.merge(profile);
}

Criar o contexto JSF exige algo um pouco mais avançado. Antes de iniciar a execução das ações, o contexto JSF deve ser criado, e para a sua criação é preciso o HttpServletRequest e o HttpServletResponse. Uma forma seria criando um filtro, mas acredito que não é uma boa solução. O Seam possui um recurso de ExecutionHandler que permite executar determinadas operações em requisições Remoting antes executar a ação. Este recurso usa o padrão Observer, onde o primeiro passo é criar o observer, ele precisa de implementar a interface ExecutionHandler:

public class RemotingFacesContextHandler extends ExecutionHandler {

private ServletContext servletContext;

protected FacesContext getFacesContext(HttpServletRequest request,
HttpServletResponse response) {

FacesContext facesContext = FacesContext.getCurrentInstance();

if (facesContext == null) {
FacesContextFactory contextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
facesContext = contextFactory.getFacesContext(servletContext,request, response, lifecycle);
}

return facesContext;
}
@Override
public void handle(HttpServletRequest request, HttpServletResponse response)
throws Exception {
getFacesContext(request, response);
super.handle(request, response);
}
@Override
public void setServletContext(ServletContext ctx) {
this.servletContext = ctx;
super.setServletContext(ctx);
}
}

O método handle chama o método getFacesContext que é responsável por iniciar o contexto. A inicialização do FacesContext é feita por meio do método getFacesContext da classe FacesContextFactory. Além do contexto servlet, do request e do response, é necessário informar o ciclo de vida JSF.O Ciclo de vida é criado por meio da classe LifecycleFactory.

Uma vez criado o observer, basta registrá-lo. Uma das várias alternativas é registrá-lo após a inicialização usando a anotação @Observe:

@Name("registerHandler")
public class RegisterFacesContextHandler {
private static final String REQUEST_PATH_EXECUTE = "/execute";

@Observer("org.jboss.seam.postInitialization")
public void initHandler() {
RequestHandlerFactory.getInstance().registerHandler(REQUEST_PATH_EXECUTE, new RemotingFacesContextHandler());

}

}

Após inicializado o Seam (org.jboss.seam.postInitialization) o observer é registrado. Com isto você pode chamar FacesContext.getCurrentInstance() que não receberá aquele NullPointerException indesejado. ;)


Viewing all articles
Browse latest Browse all 10

Latest Images

Trending Articles



Latest Images