Spring MVC Controller PathVariables上的Java bean验证

时间:2016-07-26 01:28:46

标签: spring spring-mvc kotlin bean-validation

我正在尝试使用Java Bean验证注释来处理Spring MVC控制器中的路径变量和查询参数。 (环境:Spring Boot v1.3.5,Springxxx 4.2.6,编程语言Kotlin 1.0.3)

e.g。

@RequestMapping(value = "/{someId}" ...)
fun getSomething(**@SomeValidId** @PathVariable("someId") someId: String):...

我已添加org.springframework.validation.beanvalidation.MethodValidationPostProcessor,如https://raymondhlee.wordpress.com/2015/08/29/validating-spring-mvc-request-mapping-method-parameters/中所述,并且还添加了org.springframework.validation.beanvalidation.LocalValidatorFactoryBean作为上述的validatorFactory。

@Configuration
...class .... {

...

@Bean
open fun localValidatorFactoryBean() = LocalValidatorFactoryBean()

@Bean
open fun methodValidationPostProcessor() : MethodValidationPostProcessor  {
    val methodValidationPostProcessor = MethodValidationPostProcessor()
    methodValidationPostProcessor.setValidator(localValidatorFactoryBean())

    return methodValidationPostProcessor
}

}

但是当我用Controller注释Controller类(或它实现的接口)时 org.springframework.validation.annotation.Validated看起来像控制器类是代理的(似乎是预期的 - https://github.com/spring-projects/spring-security/issues/3215)。

@Validated
interface SomeResource  {
....

@RestController
@RequestMapping("/somepath") 
class SomeController ......: SomeResource ....

但是这会导致Spring mvc请求映射设置忽略SomeController。通过Spring框架代码进行调试看起来像org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods()遍历bean列表并尝试检测处理程序方法,但上面的控制器在遇到a时看起来被它忽略了代理实例,它不带@Controller或@RequestMapping注释。

有没有人知道缺少什么?似乎有很多信息似乎表明这应该是可能的,但找不到一个有效的例子。

1 个答案:

答案 0 :(得分:2)

我找到了问题 - 这是因为为控制器创建的代理是JDK动态代理。当我强迫它成为CGLIB代理时,它开始正常工作。

默认情况下,Kotlin类是最终的,因此被迫使用JDK动态代理,但将控制器标记为“打开”。不足以强迫它使用CGLIB。不得不将@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)添加到控制器类

@RestController
@RequestMapping("/somepath") 
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
class SomeController ......: SomeResource ....