É possível fazer um interceptor executar quando a chamada vem por um forward de um outro método da controller?
Exemplo: tenho um método de uma controller que salva um usuário, após salvar faz um forward para a tela de listagem. este método de listagem tem um inteceptor e nunca é invocado
segue os códigos: UsuarioController.java
@Resource
public class UsuarioController {
private final Result result;
private final UsuarioDAO dao;
public UsuarioController(Result result, UsuarioDAO dao) {
this.result = result;
this.dao = dao;
}
@Post("/usuario/salvar")
public void salvar(Usuario usuario) throws DAOException {
usuarioDAO.insert(usuario);
result.forwardTo(this).listagem();
}
@Path("/usuario/listagem")
@Logger // ====> meu interceptor
public void listagem() throws DAOException {
List<Usuario> usuarios = usuarioDAO.list();
result.include("usuarios", usuarios);
}
}
LoggerInterceptor.java
public class LoggerInterceptor implements Interceptor {
@Override
public boolean accepts(ResourceMethod method) {
Class<? extends Annotation> tx = br.com.testes.Logger.class;
return method.containsAnnotation(tx);
}
@Override
public void intercept(InterceptorStack stack, ResourceMethod method, Object resourceInstance) throws InterceptionException {
System.out.println(method.getMethod().getName());
}
}
Se eu chamo a tela de listagem direto do browser, o interceptor é invocado.
Porém quando o método listagem() é chamado a partir de um result.forwardTo(this).listagem(), o interceptor nunca é chamado.
tem como invocar o interceptor também via forward?
mas a ideia é aproveitar a mesma requisição mesmo, preciso dos dados do request do primeiro método executado da controller.
a dúvida é se o vraptor consegue invocar um interceptor se ele começa por um forward. Ou seja, se o interceptor está atrelado ao bean da controller ou apenas no começo do request
o código que postei em si é só um exemplo. mas em diversas partes do sistema eu tenho que fazer um forward mesmo, nao um redirect.
é atrelado só a um novo request sim… acabei de ver nos fontes do vraptor.
aí tive outra ideia:
uma vez que uma controller do vraptor é um bean do guice, entao se criar um interceptor para o guice deve resolver…
agora to procurando onde colocar o módulo Guice que faz o bind dos interceptors… talvez vou ter que cirar um novo Provider estendendo do GuiceProvider e adicionar o módulo no injector do VRaptor… mas ainda nao sei se é a melhor opção
o forwardTo do VRaptor é de “mentira”, ele só executa o método do outro controller na mesma requisição. O motivo pra isso é que alguns interceptors não podem rodar duas vezes (por exemplo os de transação) e iria ficar bem difícil configurar isso.
a maneira de usar um module do guice é estender GuiceProvider e sobrescrever o customModule(). Lembre-se de registrar o super.customModule() no seu módule. Esse é o ponto de extensão mesmo. Não dá pra fazer isso via injeção de dependências, pq isso tem que rodar antes da DI ficar configurada.
sim, pra testar fiz um fork do vraptor e coloquei no proxy do forward pra rodar a stack de interceptor… tive exatamente esse problema. os interceptors do primeiro método (request de origem) rodaram de novo e ainda na url de origem
[quote=Lucas Cavalcanti]
a maneira de usar um module do guice é estender GuiceProvider e sobrescrever o customModule(). Lembre-se de registrar o super.customModule() no seu módule. Esse é o ponto de extensão mesmo. Não dá pra fazer isso via injeção de dependências, pq isso tem que rodar antes da DI ficar configurada.[/quote]
amanha vou tentar dessa forma. pois acabei resolvendo criando uma nova classe com @RequestScoped que faz a transição… imitei o conteúdo o forwardTo do DefaultLogicResult e antes do invoke no proxy chamei uma classe minha que faz o trabalho do interceptor. Funcionou, mas nao fiquei satisfeito. Então vou tentar a estrategia de estender o GuiceProvider.