使用自定义HandlerMethodArgumentResolver进行Spring MVC @Valid验证

Sot*_*lis 21 java spring

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

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

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

在上面的例子中,虽然我的解析器将被调用,我的Domain论点将得到初始化,@Valid注释将不会被处理,并为解析器BindingResult,一个ErrorsMethodArgumentResolver是因为它需要一个会失败@ModelAttribute,@RequestBody@RequestPart在处理方法的说法,这我不没有.

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

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

将首先检查一个HandlerMethodArgumentResolver实现,并在我的自定义解析器之前解析参数(带和).该不会失败,但我不会对我的自定义创建行为的实例.ModelAttributeMethodProcessorsupports()@ModelAttribute@ValidBindingResultDomain

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

Bij*_*men 9

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

我查看了你已经概述的代码并得出了相同的结论 - 没有内置方法同时应用自定义 HandlerMethodArgumentResolver@Valid相关验证,唯一的选择是做什么所述ModelAttributeMethodProcessor确实这是检查该参数具有@Valid注释和调用验证逻辑相关的代码.

您可以HandlerMethodResolverArgumentResolver从这个方式派生出来ModelAttributeMethodProcessorsuper.validateIfApplicable(..)至少调用现有代码.


Ale*_*rer 5

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

Object resolvedObject = // your logic 
if(parameter.hasParameterAnnotation(Valid.class){
            binderFactory.createBinder(webRequest,resolvedObject,"resolvedObjectLogicalName").validate ();
}
Run Code Online (Sandbox Code Playgroud)

  • 我不得不这样做:``` WebDataBinder binder = binderFactory.createBinder(webRequest, resolveObject, "resolvedObjectLogicalName"); 活页夹验证();BindingResult bindingResult = binder.getBindingResult(); if (bindingResult.getErrorCount() > 0) { throw new MethodArgumentNotValidException(parameter, bindingResult); }``` (2认同)