I'd like to set up my beans to use both Hibernate Validator (for validation) and Google Guice (for DI and method interception).

Ideally, I'd like to have a setup where any method that "fails" validation will cause a method interceptor to be called:

public class Widget {
    @NotNull
    public Fizz getFizz() {
        return fizz;
    }
}

public class FailedWidgetInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // This gets executed if Widget's getFizz() returns null...
    }
}

But it looks like Hibernate Validator only allows you to determine pass/fail status by explicitly passing an object T to a ClassValidator<T>'s getInvalidValues() method.

So I need a place to make such a call! The only viable solution I can think of is to create my own annotation (which I've never done before!) which might look like this:

@NotNull
public @interface AutoValidatingNotNull {
    // ...??
}

And then in Guice Module:

public class WidgetModule implements Module {
    public void configure(Binder binder) {
        binder.bindInterceptor(
            any(),
            annotatedWith(AutoValidatingNotNull.class),
            new ValidatingWidgetInterceptor()
        );
    }
}

public class ValidatingWidgetInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        ClassValidator<Widget> widgetValidator = new ClassValidator<Widget>();

        InvalidValue[] badVals = widgetValidator.getInvalidValues(widget);

        if(badVals.length > 0)
            handleFailedValidationAndThrowRuntimeExceptionOrSomething();
    }
}

Finally, to change getFizz():

@AutoValidatingNotNull
public Fizz getFizz() {
    return fizz;
}

For one, this only almost works: inside the interceptor's invoke method, how do I get my hands on the widget instance (the one we wish to validate)?. Is there a way to pass the widget instance via annotations?

Edit:
Doesn't look like I can pass Object into annotations (as parameters)...

Second, this is kind of nasty. Perhaps I'm overlooking something that Hibernate Validator offers that takes care of all this for me? Is there a better way to go? Thanks in advance!

有帮助吗?

解决方案

It seems like you're still using the Hibernate Validator 3.x API around ClassValidator et al.

I recommend to upgrade to 4.2 where an API for method validation was introduced which exactly does what you describe.

An example for the required glue code to integrate that API with Google Guice can be found in this project which I created a while ago on GitHub.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top