Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java EE Interceptors and @ViewScoped bean

I'm building a Java EE application using JBoss 7.1.

In order to get a full audit of the user actions, I'm planing to use Interceptors to log every invocation of my beans' methods.

To do so I have the following biding:

@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Logged {
}

Then I define my interceptor class:

@Logged
@Interceptor
public class UserActionInterceptor implements Serializable {

private static final long serialVersionUID = 1L;
private Logger log = LoggerFactory.getLogger(UserActionInterceptor.class);

public UserActionInterceptor() {
}

@AroundInvoke
public Object logMethodEntry(InvocationContext invocationContext) throws Exception {
    log.debug(invocationContext.getMethod().getName() + " invoked.");
    return invocationContext.proceed();
    }
}

So far this is working fine. If I bind a class using this Interceptor I do get some logging. However it gets trickier when I want to target my beans classes.

If I have a bean of type @RequestScoped and bind it to my interceptor it works. However, if I have a bean of type @ViewScoped then it doesn't.

I looked up the definition of @ViewScoped and I found:

@Retention(value=RUNTIME)
@Target(value=TYPE)
@Inherited
public @interface ViewScoped

I have the feeling that the problem lies in the fact that this annotation doesn't have the target type METHOD and that it prevents my interceptor to intercept calls to the class methods.

Has anyone had the same issue before? Does someone know if it is possible to extend the scope of the bean so that its methods can be intercepted without changing the nature of the @ViewScoped?

like image 583
phoenix7360 Avatar asked Oct 11 '12 14:10

phoenix7360


1 Answers

This happens because the interceptor can not access the @ManagedBean. @ViewScope is not part of the CDI and it comes with JSF beans.

In order to make it work, the surest way is to use @ViewScoped with CDI by using one of the extensions that provides it. Your options include MyFaces CODI and Seam 3 (for example).

I have got it working (the same way you describe it) by installing MyFaces CODI and using the following annotations with these imports:

import javax.faces.bean.ViewScoped;
import javax.inject.Named;

@Named
@ViewScoped
@Interceptors({ MyInterceptor.class})
like image 162
bjedrzejewski Avatar answered Dec 05 '22 10:12

bjedrzejewski