使用自定义HandlerMethodArgumentResolver进行Spring MVC @Validvalidation
我想注册一个可以处理以下@Controller
处理程序方法定义的自定义HandlerMethodArgumentResolver
@RequestMapping(method = RequestMethod.POST) public String createDomain(@Valid Domain domain, BindingResult errors, @RequestParam("countryId") Long countryId) {
我可以通过覆盖addArgumentResolver()
来注册我的解析器,它只是通过请求参数创建一个Domain
对象。 当Spring尝试解析Domain
参数时,它会通过其HandlerMethodArgumentResolver
列表(有很多)并选择supports()
的第一个。
在上面的例子中,虽然我的解析器将被调用并且我的Domain
参数将被初始化,但@Valid
注释将不会被处理, 并且 BindingResult
的解析器, ErrorsMethodArgumentResolver
将失败,因为它需要BindingResult
, ErrorsMethodArgumentResolver
或者处理程序方法中的@RequestPart
参数,我没有。
如果我尝试通过添加@ModelAttribute
来修复它
@RequestMapping(method = RequestMethod.POST) public String createDomain(@Valid @ModelAttribute Domain domain, BindingResult errors, @RequestParam("countryId") Long countryId) {
HandlerMethodArgumentResolver
实现ModelAttributeMethodProcessor
将首先使用supports()
进行检查,并在我的自定义解析器之前解析参数(使用@ModelAttribute
和@Valid
)。 BindingResult
不会失败,但我不会在Domain
实例上拥有自定义创建行为。
我可以复制粘贴代码进行validation并添加到ModelAttributeMethodProcessor
模型,但我希望有一种更简单的方法来解析我的参数并执行validation而无需向模型添加对象。 有这样的方式吗?
很好地描述了您所面临的问题。
我检查了你已经概述的代码并得出了相同的结论 – 没有内置方法同时应用自定义HandlerMethodArgumentResolver
以及@Valid
相关validation,唯一的选择是执行ModelAttributeMethodProcessor
所做的工作,检查参数是否具有@Valid
注释并调用与validation逻辑相关的代码。
你可以从ModelAttributeMethodProcessor
派生你的HandlerMethodResolverArgumentResolver
并调用super.validateIfApplicable(..)
至少以这种方式利用现有代码。
这可能为时已晚,但您的HandlerMethodArgumentResolver
将WebDataBinderFactory
对象作为最后一个参数获取,然后,为了连接validation,只需将其添加到您的解析器实现中:
Object resolvedObject = // your logic if(parameter.hasParameterAnnotation(Valid.class){ binderFactory.createBinder(webRequest,resolvedObject,"resolvedObjectLogicalName").validate (); }