web-dev-qa-db-fra.com

Un argument Errors / BindingResult devrait être déclaré immédiatement après l'attribut de modèle, les arguments @RequestBody ou @RequestPart

J'enseigne moi-même Spring en disséquant des exemples d'applications puis en ajoutant du code ici et là pour tester les théories que je développe pendant la dissection. Je reçois le message d'erreur suivant lors du test d'un code que j'ai ajouté à une application Spring:

An Errors/BindingResult argument is expected to be declared immediately after the  
model attribute, the @RequestBody or the @RequestPart arguments to which they apply  

La méthode à laquelle le message d'erreur se réfère est:

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(Integer typeID, BindingResult result, Map<String, Object> model) {
    // find owners of a specific type of pet
    typeID = 1;//this is just a placeholder
    Collection<Owner> results = this.clinicService.findOwnerByPetType(typeID);
    model.put("selections", results);
    return "owners/catowners";
}  

Ce message d'erreur a été déclenché lorsque j'ai essayé de charger le modèle d'URL/catowners dans le navigateur Web. J'ai revu cette page et cette publication , mais l'explication ne semble pas claire.

Quelqu'un peut-il me montrer comment corriger cette erreur et également expliquer ce que cela signifie?

ÉDITER:
Sur la base de la réponse de Biju Kunjummen, j'ai changé la syntaxe comme suit:

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(@Valid Integer typeID, BindingResult result, Map<String, Object> model)  

Je reçois toujours le même message d'erreur. Y a-t-il quelque chose que je ne comprends pas?

DEUXIÈME ÉDITION:

Sur la base du commentaire de Sotirios, j'ai changé le code comme suit:

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(BindingResult result, Map<String, Object> model) {
    // find owners of a specific type of pet
    Integer typeID = 1;//this is just a placeholder
    Collection<Owner> results = this.clinicService.findOwnerByPetType(typeID);
    model.put("selections", results);
    return "owners/catowners";
 }

Je reçois toujours le même message d'erreur après avoir dit à Eclipse de s'exécuter en tant que ... exécuter à nouveau sur le serveur.

Y a-t-il quelque chose que je ne comprends pas?

22
CodeMed

Spring utilise une interface appelée HandlerMethodArgumentResolver pour résoudre le paramètre dans vos méthodes de gestionnaire et construire un objet à passer en argument.

S'il n'en trouve pas, il passe null (je dois le vérifier).

BindingResult est un objet de résultat qui contient des erreurs qui peuvent être survenues lors de la validation d'un @ModelAttribute, @Valid, @RequestBody ou @RequestPart, vous ne pouvez donc l'utiliser qu'avec des paramètres annotés en tant que tels. Il y a HandlerMethodArgumentResolver pour chacune de ces annotations.

EDIT (réponse au commentaire)

Votre exemple semble montrer que l'utilisateur doit fournir un type d'animal de compagnie (sous forme d'entier). Je changerais la méthode en

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(@RequestParam("type") Integer typeID, Map<String, Object> model)

Et vous feriez votre demande (selon votre configuration) comme

localhost:8080/yourcontext/catowners?type=1

Ici aussi, il n'y a rien à valider donc vous ne voulez pas ou n'avez pas besoin d'un BindingResult. Cela échouerait si vous essayiez de l'ajouter quand même.

18

Si vous avez un paramètre de type BindingResult, il s'agit essentiellement de conserver toute erreur lors de la liaison des paramètres de requête http à une variable déclarée précédant directement le paramètre de la méthode BindingResult.

Tout cela est donc acceptable:

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(@Valid MyType type, BindingResult result, ...)


@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(@ModelAttribute MyType type, BindingResult result, ...)

@RequestMapping(value = "/catowners", method = RequestMethod.GET)
public String findOwnersOfPetType(@RequestBody @Valid MyType type, BindingResult result, ...)
5
Biju Kunjummen