Spring MVC: veuillez expliquer la différence entre @RequestParam et @ModelAtsortingbute

Je suis nouveau sur Spring MVC. Aidez-moi à décompresser la documentation.

Documentation

Spring MVC Documentation indique (accent mis sur le mien):

  • @ModelAtsortingbute sur un argument de méthode indique que l’argument doit être extrait du modèle. S’il n’est pas présent dans le modèle, l’argument doit être instancié d’abord, puis ajouté au modèle. Une fois présents dans le modèle, les champs de l’argument doivent être renseignés à partir de tous les parameters de requête ayant des noms correspondants . La classe WebDataBinder met en correspondance les noms de parameters de requête – y compris les parameters de chaîne de requête et les champs de formulaire – pour modéliser les champs d’atsortingbut par nom.

  • @RequestParam lie les parameters de requête à un paramètre de méthode de votre contrôleur.

Disclaimer / Clarifier

Je sais que @ModelAtsortingbute et @RequestParam ne sont pas la même chose, ne sont pas mutuellement exclusifs, ne remplissent pas le même rôle et peuvent être utilisés simultanément, comme dans cette question – en effet, @RequestParam peut être utilisé pour remplir les champs de @ModelAtsortingbute . Ma question est plus orientée vers la différence entre leur fonctionnement interne.

Question:

Quelle est la différence entre @ModelAtsortingbute (utilisé sur un argument de méthode, pas sur une méthode) et @RequestParam ? Plus précisément:

  • Source: @RequestParam et @ModelAtsortingbute ont-ils la même source d’informations / population, c’est-à-dire des parameters de requête dans l’URL, qui peuvent avoir été fournis en tant qu’éléments d’un formulaire / modèle POST éd?
  • Utilisation: Est-il correct que les variables récupérées avec @RequestParam soient rejetées (à moins d’être passées dans un modèle), alors que les variables récupérées avec @ModelAtsortingbute sont automatiquement introduites dans le modèle à retourner?

Ou, dans des exemples de codage très basiques, quelle est la véritable différence entre ces deux exemples?

Exemple 1: @RequestParam :

 // foo and bar are thrown away, and are just used (eg) to control flow? @RequestMapping(method = RequestMethod.POST) public Ssortingng testFooBar(@RequestParam("foo") Ssortingng foo, @RequestParam("bar") Ssortingng bar, ModelMap model) { try { doStuff(foo, bar); } // other code } 

Exemple 2: @ModelAtsortingbute :

 // FOOBAR CLASS // Fields could of course be explicitly populated from parameters by @RequestParam public class FooBar{ private Ssortingng foo; private Ssortingng bar; // plus set() and get() methods } // CONTROLLER // Foo and Bar become part of the model to be returned for the next view? @RequestMapping(method = RequestMethod.POST) public Ssortingng setupForm(@ModelAtsortingbute("fooBar") FooBar foobar) { Ssortingng foo = fooBar.getFoo(); Ssortingng bar = fooBar.getBar(); try { doStuff(foo, bar); } // other code } 

Ma compréhension actuelle:

@ModelAtsortingbute et @RequestParam interrogent les parameters de la requête pour obtenir des informations, mais ils utilisent ces informations différemment:

  • @RequestParam ne remplit que les variables autonomes (qui peuvent bien sûr être des champs dans une classe @ModelAtsortingbute ). Ces variables seront rejetées lorsque le contrôleur est terminé, sauf si elles ont été introduites dans le modèle.

  • @ModelAtsortingbute remplit les champs d’une classe, qui remplit ensuite un atsortingbut du modèle à renvoyer à la vue

Est-ce correct?

@RequestParam ne remplit que les variables autonomes (qui peuvent bien sûr être des champs dans une classe @ModelAtsortingbute ). Ces variables seront rejetées lorsque le contrôleur est terminé, sauf si elles ont été introduites dans le modèle.

Ne confondez pas le mot “modèle” avec la session. La conversation http est généralement: HTTP.GET , réponse du serveur, puis HTTP.POST . Lorsque l’annotation @ModelAtsortingbute utilisée, vous construisez toujours une instance de ce que vous avez annoté, c’est ce qui vous fait penser que “alimenter le modèle” peut faire en sorte que les variables restnt présentes. Ce n’est pas correct, une fois que le HttpServletRequest est terminé, ces variables ne devraient plus faire partie de la conversation entre le navigateur et le serveur, sauf si elles ont été enregistrées dans une session.

@ModelAtsortingbute remplit les champs d’une classe, qui remplit ensuite un atsortingbut du modèle à renvoyer à la vue

Oui! Pour être correct, @ModelAtsortingbute dit à Spring d’utiliser son classeur de données Web par défaut pour remplir une instance de quelque chose avec des données provenant de HttpServletRequest . Le choix de transmettre ces données à la vue revient au programmeur. Lorsque vous avez une méthode annotée avec @ModelAtsortingbute , elle est appelée à chaque fois que le code frappe cette servlet. Lorsque vous avez @ModelAtsortingbute comme l’un des parameters de la méthode, nous parlons de la liaison des données du formulaire HTTP entrant.

L’appel de @RequestParam est un raccourci pour dire request.getParameter("foo") ; Sous le capot, Java HttpServletRequest vous permet d’obtenir des valeurs à partir de l’object de la requête en effectuant une recherche clé-valeur. La valeur renvoyée est de type Object. C’est ce que vous taperiez beaucoup si vous n’utilisiez pas Spring dans votre application Web.

Spring prend ensuite cette abstraction un peu plus loin lorsque vous commencez à utiliser @ModelAtsortingbute . Cette annotation utilise le concept de liaison de données. Le but de la liaison de données est que le code de votre contrôleur n’ait pas à appeler request.getParameter("foo1") , pour chaque élément de formulaire. Imaginez que vous avez un formulaire Web avec 5 champs. Sans liaison de données, le programmeur doit récupérer et valider manuellement chacun de ces champs. Le programmeur doit s’assurer que la demande contient la propriété, que la valeur de la propriété existe et que la valeur de la propriété est du type attendu pour chaque champ. Utiliser @ModelAtsortingbute dit à Spring de faire ce travail pour vous.

Si vous annotez une méthode dans votre contrôleur avec @ModelAtsortingbute("fooBar") FooBar fooBar Une instance de FooBar sera toujours construite par Spring et fournie à votre méthode. Lorsque la liaison de données entre en jeu, c’est lorsque cette annotation est utilisée dans les parameters d’une méthode; Spring examine l’instance de HttpServletRequest et voit si elle peut faire correspondre les données de la requête à la propriété correcte sur une instance de FooBar . Ceci est basé sur la convention de propriétés java, où vous avez un champ tel que foo et les getters et setters getFoo appelés getFoo et setFoo . Cela peut sembler magique, mais si vous deviez rompre la convention, votre liaison de données Spring cesserait de fonctionner car elle ne pourrait pas savoir lier les données de votre HttpServletRequest Vous obtiendriez FooBar même une instance de FooBar , mais les propriétés ne être défini sur les valeurs de la requête.

@ModelAtsortingbute parameters annotés @ModelAtsortingbute sont gérés par un ServletModelAtsortingbuteMethodProcessor (ou ModelAtsortingbuteMethodProcessor ) ModelAtsortingbuteMethodProcessor et les parameters annotés @ModelAtsortingbute sont gérés par un ServletModelAtsortingbuteMethodProcessor ou un ModelAtsortingbuteMethodProcessor enregistré en fonction du type de paramètre.

Voici une explication de la façon dont Spring utilise ces HandlerMethodArgumentResolvers pour résoudre les arguments de vos méthodes de gestionnaire:

  • Formulaire à soumettre dans Spring MVC 3 – explication

Dans les deux cas, @ModelAtsortingbute et @RequestParam , les valeurs à lier sont extraites des parameters ServletRequest .

Vous pouvez regarder le code source des types mentionnés ci-dessus, mais voici les détails simples.

Pour @ModelAtsortingbute , Spring créera une instance du type de paramètre. Il inspectera les champs de cette instance et tentera de leur @ModelAtsortingbute valeurs de parameters basées sur une stratégie de dénomination / aliasing composée du nom @ModelAtsortingbute et des noms de champs. Il utilise généralement un groupe d’instances de Converter pour convertir de la Ssortingng (les valeurs de paramètre sont toujours des valeurs de Ssortingng ) vers le type de champ cible Integer , Date , etc. Vous pouvez également enregistrer vos propres types de Converter pour les conversions personnalisées. Vous pouvez également imbriquer les types POJO.

Pour @RequestParam , Spring utilisera les mêmes instances de Converter pour convertir directement les valeurs de paramètre en type de paramètre annoté.

Notez que les valeurs des parameters ne sont pas “jetées”. Ils sont stockés dans HttpServletRequest pour la durée du cycle de traitement des requêtes du conteneur. Vous pouvez toujours y accéder via les méthodes appropriées .

@ModelAtsortingbute : lie un object Java entier (comme Employee). prend en charge plusieurs parameters de demande

@RequestParam : lie un seul paramètre de requête (comme firstName)

En général,
@RequestParam est @RequestParam pour lire un petit nombre de parameters.

@ModelAtsortingbute est utilisé lorsque vous avez un formulaire avec un grand nombre de champs.

et

@ModelAtsortingbute vous offre des fonctionnalités supplémentaires telles que la liaison de données, la validation et la préparation des formulaires.

@ModelAtsortingbute (paramètre) charge un atsortingbut de modèle à partir de @SessionAtsortingbutes ou de @ModelAtsortingbute (méthode) .

Vous n’en avez pas besoin uniquement pour lier des valeurs à partir d’une requête, mais cela se fera après le chargement depuis @SessionAtsortingbutes .

@RequestParam lie un paramètre de requête à un object.

  • Au niveau de la méthode

Lorsque l’annotation est utilisée au niveau de la méthode, elle indique que le but de cette méthode est d’append un ou plusieurs atsortingbuts de modèle. Ces méthodes prennent en charge les mêmes types d’argument que les méthodes @RequestMapping , mais elles ne peuvent pas être directement mappées aux requêtes.

 @ModelAtsortingbute public void addAtsortingbutes(Model model) { model.addAtsortingbute("msg", "Welcome to the Netherlands!"); } 

Une méthode qui ajoute un atsortingbut nommé msg à tous les modèles définis dans la classe du contrôleur.

Spring-MVC appellera toujours cette méthode avant d’appeler des méthodes de gestionnaire de requêtes. C’est-à-dire que les méthodes @ModelAtsortingbute sont appelées avant que les méthodes de contrôleur annotées avec @RequestMapping soient appelées. La logique derrière la séquence est la suivante: l’object modèle doit être créé avant que tout traitement ne commence dans les méthodes du contrôleur.

Il est également important d’annoter la classe respective sous la forme @ControllerAdvice. Ainsi, vous pouvez append des valeurs dans Model qui seront identifiées comme globales. Cela signifie que pour chaque requête, une valeur par défaut existe pour chaque méthode de la partie réponse.

  • Comme argument de méthode

Utilisé comme argument de méthode, il indique que l’argument doit être extrait du modèle. S’il n’est pas présent, il doit d’abord être instancié, puis ajouté au modèle et, une fois présent dans le modèle, les champs d’arguments doivent être remplis à partir de tous les parameters de requête ayant des noms correspondants.

Dans l’extrait de code qui suit l’atsortingbut de modèle utilisateur est rempli avec des données provenant d’un formulaire soumis au noeud final addUser. Spring MVC le fait en arrière-plan avant d’appeler la méthode submit:

 **@RequestMapping**(value = "/addUser", method = RequestMethod.POST) public Ssortingng submit(@ModelAtsortingbute("user") User user) { return "userView"; } 

Ainsi, il lie les données de formulaire avec un bean. Le contrôleur annoté avec @RequestMapping peut avoir des arguments de classe personnalisés annotés avec @ModelAtsortingbute.

C’est ce que l’on appelle communément la liaison de données dans Spring-MVC, un mécanisme commun qui vous évite d’avoir à parsingr chaque champ de formulaire individuellement.