--- title: Interceptors --- #When intercept? Interceptors are used to perform some task before or after a business logic like data validation, connection control, database transaction, logs and data encryption/compression. ##How to intercept? VRaptor uses an approach where the interceptor defines who will be intercepted, more closer to the interception approaches used by AOP (Aspect Oriented Programming). Therefore, to intercept a request, you need just to annotate the class with the `@Intercepts`. Like any other component, you can use scoped annotation to define the interceptor life cicle. The default scope for an interceptor is `RequestScoped`. ##A simple example The class below shows an example how to intercept all requests in a request scoped and simply show the console output that is being invoked. Remember that the interceptor is a component like any other and can receive any dependencies using Dependency Injection. ~~~ #!java @Intercepts @RequestScoped public class Log { @Inject private HttpServletRequest request; @AroundCall public void intercept(SimpleInterceptorStack stack) { System.out.println("Intercepting " + request.getRequestURI()); // code to be executed before the stack stack.next(); // execute the stack } } ~~~ To execute the code just before or after the controller execution, we can use annotations `@BeforeCall` and `@AfterCall`: ~~~ #!java @Intercepts @RequestScoped public class Log { @BeforeCall public void before() { // code executed before } @AfterCall public void after() { // code executed after } } ~~~ ##Defining when intercepting In the example above, all requests are intercepted. But we can define, as example, only methods annotated with `@Audit` annotation. You just to implement a method that returns a `boolean` with the necessary condition and annotate it with `@Accepts`. ~~~ #!java @Accepts public boolean accepts(ControllerMethod method) { return method.containsAnnotation(Audit.class); } ~~~ Or we can use the more simple way. The example above is a very common case and thus often repeat this code. For this situation we can use the annotation `@AcceptsWithAnnotations` as described below: ~~~ #!java @AcceptsWithAnnotations(Audit.class) public class AuditInterceptor { @AroundCall public void around(SimpleInterceptorStack stack) { stack.next(); } } ~~~ ##Customizing your Accepts In the example above we used a customized accepts with annotation `AcceptsWithAnnotations`. And if you need, you can create your custom annotation to define when intercepts. Before you need to create your annotation like this example below. ~~~ #!java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @AcceptsConstraint(WithAnnotationAcceptor.class) @Inherited public @interface AcceptsWithAnnotations { public Class[] value(); } ~~~ As you can see, we use the Annotation `@AcceptsConstraint` to define the class that have our logic. Now we need to implement this class. ~~~ #!java public class WithAnnotationAcceptor implements AcceptsValidator { @Override public boolean validate(ControllerMethod controllerMethod, ControllerInstance instance) { //your code here return true; } @Override public void initialize(AcceptsWithAnnotations annotation) { //your code here this.allowedTypes = Arrays.asList(annotation.value()); } } ~~~ This class needs only to implements `AcceptsValidator` interface, where generic `T` is the type of your custom annotation. ##How to guarantee the order: after and before If you need to guarantee the execution order for your interceptors, you can use the `after` and `before` attributes from the `@Intercepts` annotation. Like the example below, if you have an interceptor named `FirstInterceptor` that needs to be executed before `SecondInterceptor`, you can declare like this: ~~~ #!java @Intercepts(before=SecondInterceptor.class) public class FirstInterceptor { ... } ~~~ and: ~~~ #!java @Intercepts(after=FirstInterceptor.class) public class SecondInterceptor { ... } ~~~ You can define one more Interceptor: ~~~ #!java @Intercepts(after={FirstInterceptor.class, SecondInterceptor.class}, before={FourthInterceptor.class, FifthInterceptor.class}) public class ThirdInterceptor { ... } ~~~ Note: VRaptor throws an exception if there is a cycle in the interceptors order. So be careful when you define interceptors order to avoid cicles.