MVC @Valid Validation with custom HandlerMethodArgumentResolver
je veux enregistrer une coutume HandlerMethodArgumentResolver
qui pourrait gérer le suivant @Controller
définition de la méthode handler
@RequestMapping(method = RequestMethod.POST)
public String createDomain(@Valid Domain domain, BindingResult errors, @RequestParam("countryId") Long countryId) {
je peux enregistrer mon résolveur, ce qui crée un Domain
objet à travers les paramètres de la demande, en remplaçant addArgumentResolver()
WebMvcConfigurerAdapter
. Quand le printemps tente de résoudre le Domain
paramètre, il passe en revue sa liste de HandlerMethodArgumentResolver
(il y en a beaucoup) et prend la première qui supports()
.
Dans l'exemple ci-dessus, bien que mon résolveur obtiendrez appelé et mon Domain
l'argument sera initialisé, le @Valid
annotation de ne pas avoir été traitée et le résolveur pour BindingResult
, un ErrorsMethodArgumentResolver
échouera parce qu'il nécessite un @ModelAttribute
,@RequestBody
ou @RequestPart
argument dans la méthode handler, que je n'ai pas.
Si j'essaie de le corriger en ajoutant @ModelAttribute
@RequestMapping(method = RequestMethod.POST)
public String createDomain(@Valid @ModelAttribute Domain domain, BindingResult errors, @RequestParam("countryId") Long countryId) {
HandlerMethodArgumentResolver
mise en œuvre, ModelAttributeMethodProcessor
, sera cochée en premier avec supports()
et résolvez l'argument (avec @ModelAttribute
et @Valid
) avant mon résolveur personnalisé. BindingResult
ne pas échouer, mais je n'aurai pas ma création personnalisée comportement sur le Domain
instance.
je pourrais simplement copier-coller le code pour la validation et l'ajout au modèle qui est dans ModelAttributeMethodProcessor
, mais j'espérais qu'il y aurait un moyen plus simple de résoudre mes paramètres et d'effectuer la validation sans ajouter d'objet au modèle. Est-il une telle façon?
2 réponses
Sympa la description du problème que vous rencontrez.
j'ai vérifié le code que vous avez décrit et en suis arrivé à la même conclusion que vous avez - il n'y a pas de façon intégrée d'avoir à la fois une coutume HandlerMethodArgumentResolver
ainsi que @Valid
validation appliqués au même moment, le seul choix est de faire ce que l' ModelAttributeMethodProcessor
fait qui est de vérifier si le paramètre a un @Valid
annoter et appeler le code lié à la logique de validation.
vous pouvez probablement dériver votre HandlerMethodResolverArgumentResolver
ModelAttributeMethodProcessor
et appeler super.validateIfApplicable(..)
au moins de cette façon, le code existant est mis à profit.
C'est peut-être trop tard, mais votre HandlerMethodArgumentResolver
devient WebDataBinderFactory
objet comme dernier argument, alors, pour le raccordement de la validation, il suffit de l'ajouter à votre programme de résolution de mise en œuvre:
Object resolvedObject = // your logic
if(parameter.hasParameterAnnotation(Valid.class){
binderFactory.createBinder(webRequest,resolvedObject,"resolvedObjectLogicalName").validate ();
}