21

我想注册一个HandlerMethodArgumentResolver可以处理以下@Controller处理程序方法定义的自定义

@RequestMapping(method = RequestMethod.POST)
public String createDomain(@Valid Domain domain, BindingResult errors, @RequestParam("countryId") Long countryId) {

我可以注册我的解析器,它只是Domain通过请求参数创建一个对象,方法是addArgumentResolver()WebMvcConfigurerAdapter. 当 Spring 尝试解析Domain参数时,它会遍历其列表HandlerMethodArgumentResolver(有很多)并选择supports()它的第一个。

在上面的示例中,虽然我的解析器将被调用并且我的Domain参数将被初始化,但@Valid注释不会被处理,并且解析器将失败BindingResultErrorsMethodArgumentResolver因为它需要 a或处理程序方法中的@ModelAttribute参数,而我没有没有。@RequestBody@RequestPart

如果我尝试通过添加来修复它@ModelAttribute

@RequestMapping(method = RequestMethod.POST)
public String createDomain(@Valid @ModelAttribute Domain domain, BindingResult errors, @RequestParam("countryId") Long countryId) {

一个HandlerMethodArgumentResolver实现 ,ModelAttributeMethodProcessor将在我的自定义解析器之前首先检查supports()并解析参数(使用@ModelAttributeand )。不会失败,但我不会在实例上拥有我的自定义创建@Valid行为。BindingResultDomain

我可以复制粘贴代码进行验证并添加到 中的模型ModelAttributeMethodProcessor,但我希望有一种更简单的方法来解析我的参数并执行验证,而无需向模型添加对象。有没有这样的方法?

4

2 回答 2

9

很好地描述了您所面临的问题。

我检查了您概述的代码并得出了与您相同的结论-没有内置方法可以同时应用自定义 验证HandlerMethodArgumentResolver@Valid相关验证,唯一的选择是做什么做的ModelAttributeMethodProcessor是检查参数是否有@Valid注释并调用验证逻辑相关代码。

您可能可以通过利用现有代码的方式HandlerMethodResolverArgumentResolver派生ModelAttributeMethodProcessor并调用至少。super.validateIfApplicable(..)

于 2013-08-07T00:25:01.233 回答
5

可能为时已晚,但是您HandlerMethodArgumentResolver将获取WebDataBinderFactory对象作为最后一个参数,然后,要连接验证,只需将其添加到您的解析器实现中:

Object resolvedObject = // your logic 
if(parameter.hasParameterAnnotation(Valid.class){
            binderFactory.createBinder(webRequest,resolvedObject,"resolvedObjectLogicalName").validate ();
}
于 2015-03-18T13:30:34.670 回答