2016-07-26 40 views
1

Ich versuche Java Bean-Validierungsannotationen zu erhalten, um mit Pfadvariablen und Abfrageparametern in Spring MVC-Controller zu arbeiten. (Umgebung: Spring Boot v1.3.5, Springxxx 4.2.6, Programmiersprache Kotlin 1.0.3)Java-Bean-Validierung auf Spring MVC-Controller PathVariables

z.B.

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

Ich habe hinzugefügt org.springframework.validation.beanvalidation.MethodValidationPostProcessor wie in https://raymondhlee.wordpress.com/2015/08/29/validating-spring-mvc-request-mapping-method-parameters/ beschrieben und auch als validatorFactory der oben hinzugefügt org.springframework.validation.beanvalidation.LocalValidatorFactoryBean.

@Configuration 
...class .... { 

... 

@Bean 
open fun localValidatorFactoryBean() = LocalValidatorFactoryBean() 

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

    return methodValidationPostProcessor 
} 

}

Aber wenn ich die Controller-Klasse mit Anmerkungen versehen (oder die Schnittstelle implementiert es) mit org.springframework.validation.annotation.Validated wie vorgeschlagen sieht aus wie die Controller-Klasse ist proxied (das scheint sei wie erwartet - https://github.com/spring-projects/spring-security/issues/3215).

@Validated 
interface SomeResource { 
.... 

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

Aber dies bewirkt, dass der Spring MVC Anfrage Mapping-Setup der SomeController zu ignorieren. Debugging durch den Spring-Framework-Code sah aus wie org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods() durchläuft die Liste der Beans und versucht, Handler-Methoden zu erkennen, aber der obige Controller wird von den Looks ignoriert, wenn er auf a stößt Proxy-Instanz und trägt nicht die @Controller- oder @RequestMapping-Annotationen.

Hat jemand eine Idee, was fehlt? Es scheint eine Menge Informationen zu geben, die darauf hindeuten, dass dies möglich sein sollte, aber kein funktionierendes Beispiel finden konnten.

Antwort

2

Nun, ich fand das Problem - es war, weil der Proxy für den Controller erstellt wurde ein JDK Dynamic Proxy. Als ich es gezwungen habe, ein CGLIB-Proxy zu sein, funktionierte es gut.

Standardmäßig sind Kotlin-Klassen endgültig und daher gezwungen, JDK Dynamic Proxys zu verwenden, aber das Markieren des Controllers als 'offen' reichte nicht aus, um CGLIB zu verwenden. Musste @Scope (proxyMode = ScopedProxyMode.TARGET_CLASS) zur Controller-Klasse hinzufügen