Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
414 views
in Technique[技术] by (71.8m points)

java - Spring MVC @Valid Validation with custom HandlerMethodArgumentResolver

I want to register a custom HandlerMethodArgumentResolver that could handle the following @Controller handler method definition

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

I can register my resolver, which just creates a Domain object through request parameters, by overriding addArgumentResolver() from WebMvcConfigurerAdapter. When Spring tries to resolve the Domain parameter, it goes through its list of HandlerMethodArgumentResolver (there are a lot) and picks the first one that supports() it.

In the above example, although my resolver will get called and my Domain argument will get initialized, the @Valid annotation won't have been processed and the resolver for BindingResult, an ErrorsMethodArgumentResolver will fail because it requires a @ModelAttribute, @RequestBody or the @RequestPart argument in the handler method, which I don't have.

If I try to fix it by adding @ModelAttribute

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

a HandlerMethodArgumentResolver implementation, ModelAttributeMethodProcessor, will get checked first with supports() and resolve the argument (with @ModelAttribute and @Valid) before my custom resolver. The BindingResult won't fail, but I won't have my custom creation behavior on the Domain instance.

I could just copy-paste the code for validation and adding to model that's in ModelAttributeMethodProcessor, but I was hoping there was an easier way to resolve my parameters and perform validation without adding an object to the model. Is there such a way?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Nice description of the issue that you are facing.

I checked out the code that you have outlined and have come to the same conclusion that you have - there is no built-in way to have both a custom HandlerMethodArgumentResolver as well as @Valid related validation applied at the same time, the only choice is to do what the ModelAttributeMethodProcessor does which is to check if the parameter has a @Valid annotation and call the validation logic related code.

You can probably derive your HandlerMethodResolverArgumentResolver from ModelAttributeMethodProcessor and call super.validateIfApplicable(..) atleast this way the existing code is leveraged.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...