Interceptors

Se você já usou a interface Filter ou conhece o conceito de interceptors dos outros frameworks, você vai encontrar uma funcionalidade parecida usando os interceptors do VRaptor.

O interceptor permite executar código antes da lógica de negócios e depois do redirecionamento à camada de apresentação.

  1. Para criar um interceptor, crie uma classe e implemente a interface Interceptor.
    package org.vraptor.example.interceptor;
    
    public class SimpleInterceptor implements Interceptor {
    
            private static volatile int hitCount = 0;
            private static volatile int concurrentHits = 0;
    
            public void intercept(LogicFlow flow) throws LogicException,
                            ViewException {
                            
                    // antes da lógica
                    hitCount++;
                    concurrentHits++;
                    System.out.printf("Numero do hit é %d%n", hitCount);
                    
                    // executa a lógica e redirecione para o view
                    flow.execute();
                    
                    // depois do view rendering
                    concurrentHits--;
                    System.out.println("Depois view...");
                    
            }
    
    }
  2. Agora você pode implementar o seu interceptor na qualquer lógica, por exemplo:
    package org.vraptor.example.interceptor;
    
    @Component("simple")
    @InterceptedBy(SimpleInterceptor.class)
    public class InterceptedTest {
    
            public void test() {
                    try {
                            System.out.println("Vamos dormir um pouco ...");
                            Thread.sleep(10000);
                    } catch(InterruptedException ex) {
                            ex.printStackTrace();
                    }
            }
            
    }
  3. Você deve criar o arquivo para o resultado : simple/test.ok.jsp e não esqueça configurar o vraptor:

    simple/test.ok.jsp

    <html>
    <%
    System.out.println("Oi scriplet!");
    // nota: nunca use scriplet na aplicação real!
    %>
    Done...
    </html>
  4. Chama o url simple.test.logic, o sistema imprime:
    Numero do hit eh 1
    Vamos dormir um pouco ...
    Oi scriplet!
    Depois view...

    Observe que o interceptor imprime a primeira linha antes de chamar flow.execute, na seqüencia o componente com a lógica de negócios é executado(segunda linha).

    O redirecionamento (terceira linha) e o resto do método intercept são executados depois (última linha).

    Então temos o fluxo seguinte:

    Criar Interceptor --> Chamar o método intercept -->
    
    Criar o Componente de Negócios --> Ler Parâmetros --> 
    
    Chamar o Método da Lógica--> Redirecionamento ao View --> 
    
    Finalização do Método intercept
    

Multiple Interceptors

Você pode usar a anotação @InterceptedBy com vários Interceptors:

@InterceptedBy( { Interceptor1.class, Interceptor2.class } )

Se tiver com uma lista de interceptadores, você pode agrupá-los usando uma pilha (InterceptorStack):

Simplesmente estenda a classe InterceptorStack e chame super passando os seus interceptadores.

Por exemplo:

public static class CommonInterceptors extends InterceptorStack {
        public Stack() {
                super(DaoInterceptor.class, UserLoginInterceptor.class);
        }
}

Ao invés de listar todos os interceptadores:

@InterceptedBy( { DaoInterceptor.class, UserLoginInterceptor.class } )

você usa a pilha:

@InterceptedBy( { CommonInterceptors.class } )