Michael
Michael

Reputation: 422

Is there possible to intercept method like this by using Guice?

This is my first post in here, Have a nice day everybody :)

I created an annotation named "Validate"

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Validate {
    Class<? extends MethodInterceptor>[] value();
}

Then decorate it before a method which need to be intercepted.

@Validate({OneInterceptor.class, TwoInterceptor.class})
public void doPost(HttpServletRequest req, HttpServletResponse resp) {
    //Do something
}


OneInterceptor implements MethodInterceptor {.....}  TwoInterceptor implements MethodInterceptor{....}

Is there a possible to bind interceptors like this by using Guice ? I just want to Guice binds these interceptors in the Run-time dynamically. Thanks everybody!

Upvotes: 1

Views: 440

Answers (2)

Jeff Bowman
Jeff Bowman

Reputation: 95614

As mlk noted, you can write a MethodInterceptor that does this, though there's no reason that the validators mentioned have to be MethodInterceptors as well--and, in fact, it will likely be easier that way because you don't have to worry about proceed().

Please pardon me if this code doesn't compile, but it should point you in the right direction:

public interface RequestValidator {
  void validate(HttpServletRequest req) throws ValidationError;
}

public class ValidationModule extends AbstractModule {
  @Override public void configure() {
    bindInterceptor(Matchers.any(), Matchers.annotatedWith(Validate.class), 
        new ValidateInterceptor());
  }
}

public class ValidateInterceptor implements MethodInterceptor {
  @Override public Object invoke(MethodInvocation invocation) throws Throwable {
    Method method = invocation.getMethod();
    Validate validate = method.getAnnotation(Validate.class);
    if (validate == null) {
      throw new IllegalStateException(
          "ValidateInterceptor installed on non-@Validate method");
    }
    for (Class<? extends RequestValidator> validatorClass : validate.value()) {
      RequestValidator validator = validatorClass.newInstance();
      validator.validate((HttpServletRequest) invocation.getArguments()[0]);
    }
    return invocation.proceed();
  }
}

Upvotes: 3

Michael Lloyd Lee mlk
Michael Lloyd Lee mlk

Reputation: 14661

Why do you want to do it this way? Why not create two annotations?

I don't believe you can do directly, but you could write a MethodInterceptor that executed the MethodInterceptors in the methods annotation. But again, why?

Upvotes: 0

Related Questions