Como Interceptar Controller especifico?

13 respostas
H

Quero que um determinado Interceptor intercepte apenas alguns metodos especificos de determinados controllers.

Como faço isso? Não encontrei na documentação.

Abraço a todos.

Fiquem com Deus.

13 Respostas

G

heliortf, você quer saber isso no vraptor? 2.6 ou 3? Hmm, vou te passar a dica no vr3.

Eu fiz uma receita de bolo sobre um no-cache interceptor. Aqui o artigo: http://vraptor.caelum.com.br/cookbook/evitando-que-o-browser-faca-cache-das-paginas/

Nesse caso note que o accepts retorna sempre true. Então nele você adiciona as condições para interceptar. Digamos que eu queria interceptar somente o AuthenticationController;

@Intercepts
@RequestScoped
public class NoCacheInterceptor
    implements Interceptor {

    private final HttpServletResponse response;

    public NoCacheInterceptor(HttpServletResponse response) {
        this.response = response;
    }

    @Override
    public boolean accepts(ResourceMethod method) {
        return method.getMethod().getDeclaringClass() == AuthenticationController.class;
    }

    @Override
    public void intercept(InterceptorStack stack, ResourceMethod method, Object resourceInstance)
        throws InterceptionException {
        [...]
        stack.next(method, resourceInstance);
    }
}

Se você quiser apenas um método especifico dessa classe pode usar:

@Override
    public boolean accepts(ResourceMethod method) {
        return method.getMethod().getDeclaringClass() == AuthenticationController.class && method.getMethod().getName().equals("store");
    }

Isso pode te ajudar? Abraços

Lucas_Cavalcanti

No VRaptor3 né?

os interceptors têm um método accepts, que deve retornar true se vc vai interceptar a classe:

public boolean accepts(ResourceMethod method) {
       //method.getMethod() é o método java que está sendo interceptado
      // method.getResource().getType() é a classe do controller que está sendo interceptado
      return method.getMethod().getName().equals("umMetodo");
}

um jeito mais legal de fazer isso, é criar uma anotação simples, e anotá-la nos métodos:

@Retention(RUNTIME)
@Target(METHOD)
public @interface Interceptavel {
}
@Intercepts
public class MeuInterceptor implements Interceptor {
     public boolean accepts(ResourceMethod method) {
           return method.getMethod().isAnnotationPresent(Interceptavel.class);
     }
}

[]'s

G

lucascs, aproveitando o gancho, sobre aquela questão da inicialização do interceptor antes de chamar o accepts, como fica para as próximas versões?

Abraços

Lucas_Cavalcanti

não é nem um pouco trivial fazer o lazy funcionar, pois não é o VRaptor que gerencia as dependências, é o Spring…

mas você pode adotar a tática do lavieri: http://vraptor.caelum.com.br/cookbook/poupando-recursos-lazy-dependency-injection/

a outra saída, a de criar um método estatico pode até funcionar… mas não está agendada pra próxima versão (3.0.2)
talvez pra 3.0.3…

se considerar extremamente necessário, a gente pode puxar essa feature pra mais perto

G

lucascs, na verdade eu não sou fã do lazy nesse caso. Mas acho conveniente ter uma forma de testar o accept sem inicializar a classe. Em outro tópico sugeri adicionar um parametro na anotação @intercepts onde eu pudesse especificar um ignore ou coisa assim.

Abraços

Lavieri

garcia-jj:
lucascs, na verdade eu não sou fã do lazy nesse caso. Mas acho conveniente ter uma forma de testar o accept sem inicializar a classe. Em outro tópico sugeri adicionar um parametro na anotação @intercepts onde eu pudesse especificar um ignore ou coisa assim.

Abraços

essa foi ate a primeira sugestão para resolver o meu problema, poder indicar no @Intercepts uma classe para aceitar alterando a @intraface assim

public @interface Intercepts { Class<?> acceptor() default void.class; }

isso para o caso de 1 acceptor, ou então se fosse o caso poder implementar multiplos acceptors externos

public @interface Intercepts { Class[] acceptors() default {}; }

Lavieri

heliortf:
Quero que um determinado Interceptor intercepte apenas alguns metodos especificos de determinados controllers.

Como faço isso? Não encontrei na documentação.

Abraço a todos.

Fiquem com Deus.

vc pode usar anotação para fazer isso… pode anotar alguns controles que deseja interceptar, e só intercepar estes… segue um exemplo aqui

http://vraptor.caelum.com.br/cookbook/interceptando-recursos-anotados/

G

Nessa minha sugestão eu estava pensando em algo built-in no próprio vraptor, assim não preciso ficar sobrescrevendo muitas convenções do vraptor.

wariows

Se não me engano, o JBoss Seam só injeta proxies… vou procurar algo sobre lazy injection com o spring…

[]'s

H

Nossa, muito obrigado! Era no vraptor 3 mesmo.

Parabéns aos desenvolvedores do vraptor, ta ficando muito bom o framework.

Eu programo em php e rails. Não programava com java pra web pq achava os frameworks muito burocráticos pra tudo. Agora que estou usando vraptor fico muito mais a vontade pra desenvolver pra web pq traz muitas facilidades.

Vai ai uma sugestão que eu acho que ficaria muuuito bom.

No rails, existe uma facilidade no roteamento das urls que é o seguinte:

map.pagina_principal “/home”, :controller => :home, :action => :index

Vi que no vraptor temos essa facilidade com os CustomRoutes, achei legal. Mas a jogada principal do roteamento do rails é que na view, eu chamo essa url assim:

pagina_principal_url

e não o link em sí “/home”

o que facilita muito quando precisa mudar o link de uma rota pq todas as views mudarão automaticamente. Acho que se existisse uma forma de fazer algo similar no vraptor ficaria excelente. Seria algo como dar um nome à url, e incluir o objeto no result pra ser visto na view.

ai poderiamos fazer algo do tipo ${routes.pagina_principal}

Espero que possam melhorar o vraptor cada vez mais. Estão de parabéns.

Abraço

G

heliortf, essa semana eu estava pensando em algo parecido. Uso mas não gosto da waffle. Então pensei em fazer um pacote de taglibs que possam trabalhar bem com XHTML e que eu possa amarrar um pouco ao meu controller, no caso o vraptor3.

No caso de um form eu pensei em fazer algo como <xx:form action=“minha_rota”> e dessa forma a taglib, que teria acesso ao Router faria a conversão para o URL. Mas aí com a correria do projeto aqui não consegui mais pensar nisso.

Abraços

H

é uma boa essa ideia das taglibs

mas nesse caso eu acharia melhor uma do tpo <xx:route value=“minha_rota” /> pq ai vc deixa o cara usar o form q ele quiser. Pq ai o vraptor ficaria mais “maleavel”

Gostei da ideia das taglibs.

Lucas_Cavalcanti

Muito boa essa idéia das taglibs sim!

a gente pensa em fazer coisas pra view em breve… nessas primeiras versões do VRaptor a gente se concentrou no
controlador mesmo…

taglibs, e funções para gerar links de forms, para gerar json, xml e coisas do tipo…

obrigado pelas sugestões pessoal =)

Criado 28 de outubro de 2009
Ultima resposta 29 de out. de 2009
Respostas 13
Participantes 5