Hibernate Validator: Intercept Invalid Values

≯℡__Kan透↙ 提交于 2019-12-08 06:31:49

问题


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!


回答1:


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.



来源:https://stackoverflow.com/questions/8853795/hibernate-validator-intercept-invalid-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!