服务层的弹簧@Validated

2022-09-01 06:03:32

海杰,

我想在执行如下方法之前使用注释来验证参数:@Validated(group=Foo.class)

public void doFoo(Foo @Validated(groups=Foo.class) foo){}

当我将此方法放在Spring应用程序的控制器中时,将执行并在Foo对象无效时引发错误。但是,如果我在应用程序的服务层的方法中放置相同的内容,则不会执行验证,并且即使 Foo 对象无效,该方法也只是运行。@Validated

您不能在服务图层中使用注记吗?还是我必须做一些额外的配置才能使其工作?@Validated

更新:

我已将以下两个bean添加到我的服务中.xml:

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>

并替换为如下所示:@Validate@Null

public void doFoo(Foo @Null(groups=Foo.class) foo){}

我知道这是一个非常愚蠢的注释,但我想检查一下,如果我现在调用该方法并传递null,它会引发一个违反异常。那么为什么它执行注释而不是注释呢?我知道一个来自春天,另一个来自春天,但我认为这与它没有任何关系?@Null@Validatejavax.validation


答案 1

在Spring MVC堆栈的眼中,没有服务层这样的东西。它适用于类处理程序方法的原因是,Spring使用一个特殊的调用,该方法在解析要在处理程序方法中使用的参数之前执行验证。@ControllerHandlerMethodArgumentResolverModelAttributeMethodProcessor

服务层,正如我们所称,只是一个普通的bean,没有从MVC()堆栈添加到它的其他行为。因此,您不能期望从春季获得任何验证。您需要自己滚动,可能使用AOP。DispatcherServlet


有了 ,看看 javadocMethodValidationPostProcessor

适用的方法在其参数和/或其返回值(在后一种情况下,在方法级别指定,通常作为内联注释)具有 JSR-303 约束注释。

验证组可以通过Spring的验证注释在包含目标类的类型级别指定,应用于该类的所有公共服务方法。缺省情况下,JSR-303 将仅针对其缺省组进行验证。

批注仅用于指定验证组,它本身不会强制任何验证。您需要使用其中一个批注,如 或 。请记住,您可以对方法参数使用任意数量的批注。@Validatedjavax.validation@Null@Valid


答案 2

作为方法的弹簧验证的旁注:

由于Spring在其方法中使用拦截器,因此只有在您与Bean方法交谈时才会执行验证本身:

当通过Spring或JSR-303 Validator接口与此bean的实例交谈时,您将与底层VeristatorFactory的默认Verganator进行对话。这非常方便,因为您不必在工厂上执行另一个调用,假设您几乎总是使用默认的验证器。

这很重要,因为如果您尝试以这种方式为类中的方法调用实现验证,则它将无法正常工作。例如:

@Autowired
WannaValidate service;
//...
service.callMeOutside(new Form);

@Service
public class WannaValidate {

    /* Spring Validation will work fine when executed from outside, as above */
    @Validated
    public void callMeOutside(@Valid Form form) {
         AnotherForm anotherForm = new AnotherForm(form);
         callMeInside(anotherForm);
    }

    /* Spring Validation won't work for AnotherForm if executed from inner method */
    @Validated
    public void callMeInside(@Valid AnotherForm form) {
         // stuff
    }        
}

希望有人觉得这有帮助。使用Spring 4.3进行了测试,因此其他版本的情况可能会有所不同。


推荐