Gestion des données de formulaire encodées par URL dans Spring REST

Haut REST

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS

1. Vue d'ensemble

Pour un utilisateur final, le processus de soumission de formulaire est pratique et, dans une certaine mesure, équivaut à simplement saisir des données et à cliquer sur un bouton d'envoi. Cependant, du point de vue de l'ingénierie, il faut un mécanisme de codage pour envoyer et recevoir de manière fiable ces données du côté client vers le côté serveur pour le traitement back-end.

Pour la portée de ce didacticiel, nous nous concentrerons sur la création d'un formulaire qui envoie ses données en tant que type de contenu application / x-www-form-urlencoded dans une application Web Spring.

2. Encodage des données de formulaire

La méthode HTTP la plus couramment utilisée pour les soumissions de formulaires est POST. Cependant, pour les soumissions de formulaires idempotents, nous pouvons également utiliser la méthode HTTP GET. Et, la manière de spécifier la méthode est via l'attribut method du formulaire.

Pour les formulaires qui utilisent la méthode GET, toutes les données du formulaire sont envoyées dans le cadre de la chaîne de requête. Mais, si nous utilisons la méthode POST, ses données sont envoyées dans le cadre du corps de la requête HTTP.

De plus, dans ce dernier cas, nous pouvons également spécifier le codage des données avec l' attribut enctype du formulaire , qui peut prendre deux valeurs, à savoir application / x-www-form-urlencoded et multipart / form-data .

2.1. Application de type de média / x-www-form-urlencoded

Les formulaires HTML ont une valeur par défaut d' application / x-www-form-urlencoded pour l' attribut enctype car cela prend en charge les cas d'utilisation de base où les données sont entièrement du texte. Néanmoins, si notre cas d'utilisation implique des données de fichier de support, nous devrons le remplacer par une valeur de multipart / form-data .

Essentiellement, il envoie les données du formulaire sous forme de paires clé-valeur séparées par une esperluette (&). En outre, la clé et la valeur respectives sont séparées par le signe égal (=). En outre, tous les caractères réservés et non alphanumériques sont codés à l'aide d'un codage en pourcentage.

3. Soumission de formulaire dans le navigateur

Maintenant que nous avons couvert nos bases, allons-y et voyons comment nous pouvons gérer les données de formulaire encodées en URL pour un cas d'utilisation simple de soumission de commentaires dans une application Web Spring.

3.1. Modèle de domaine

Pour notre formulaire de commentaires, nous devons capturer l'identifiant de courrier électronique de l'expéditeur avec le commentaire. Alors, créons notre modèle de domaine dans une classe Feedback :

public class Feedback { private String emailId; private String comment; }

3.2. Créer un formulaire

Pour utiliser un modèle HTML simple pour créer notre formulaire Web dynamique, nous devrons configurer Thymeleaf dans notre projet. Après cela, nous sommes prêts à ajouter un point de terminaison / commentaires GET qui servira la vue de commentaires pour le formulaire :

@GetMapping(path = "/feedback") public String getFeedbackForm(Model model) { Feedback feedback = new Feedback(); model.addAttribute("feedback", feedback); return "feedback"; }

Notez que nous utilisons les commentaires comme attribut de modèle pour capturer l'entrée de l'utilisateur. Ensuite, créons la vue de commentaires dans le modèle feedback.html :

Bien sûr, nous n'avons pas besoin de spécifier explicitement l' attribut enctype car il choisira la valeur par défaut de application / x-www-form-urlencoded .

3.3. PRG Flow

Comme nous acceptons les entrées des utilisateurs via le formulaire de commentaires du navigateur, nous devons implémenter le flux de travail de soumission POST / REDIRECT / GET (PRG) pour éviter les soumissions en double .

Tout d'abord, implémentons le point de terminaison POST / web / feedback qui agira en tant que gestionnaire d'actions pour le formulaire de commentaires:

@PostMapping( path = "/web/feedback", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE}) public String handleBrowserSubmissions(Feedback feedback) throws Exception { // Save feedback data return "redirect:/feedback/success"; }

Ensuite, nous pouvons implémenter le point de terminaison / feedback / succès de redirection qui sert une requête GET:

@GetMapping("/feedback/success") public ResponseEntity getSuccess() { return new ResponseEntity("Thank you for submitting feedback.", HttpStatus.OK); }

Pour valider la fonctionnalité du flux de travail de soumission de formulaire dans un navigateur, visitons localhost: 8080 / feedback :

Enfin, nous pouvons également vérifier que les données du formulaire sont envoyées sous la forme encodée en URL:

emailId=abc%40example.com&comment=Sample+Feedback

4. Demandes non-navigateur

Parfois, nous n'avons peut-être pas de client HTTP basé sur un navigateur. Au lieu de cela, notre client pourrait être un utilitaire tel que cURL ou Postman. Dans un tel cas, nous n'avons pas besoin du formulaire Web HTML. Au lieu de cela, nous pouvons implémenter un point de terminaison / feedback qui sert la requête POST:

@PostMapping( path = "/feedback", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE}) public ResponseEntity handleNonBrowserSubmissions(@RequestBody Feedback feedback) throws Exception { // Save feedback data return new ResponseEntity("Thank you for submitting feedback", HttpStatus.OK); }

En l'absence du formulaire HTML dans notre flux de données, nous n'avons pas nécessairement besoin d'implémenter le modèle PRG. Cependant, nous devons spécifier que la ressource accepte le type de média APPLICATION_FORM_URLENCODED_VALUE .

Enfin, nous pouvons le tester avec une requête cURL:

curl -X POST \ //localhost:8080/feedback \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'emailId=abc%40example.com&comment=Sample%20Feedback'

4.1. Principes de base de FormHttpMessageConverter

Une requête HTTP qui envoie des données application / x-www-form-urlencoded doit le spécifier dans l'en - tête Content-Type . En interne, Spring utilise la classe FormHttpMessageConverter pour lire ces données et les lier avec le paramètre de méthode.

In cases where our method parameter is of a type MultiValueMap, we can use either the @RequestParam or @RequestBody annotation to bind it appropriately with the body of the HTTP request. That's because the Servlet API combines the query parameters and form data into a single map called parameters, and that includes automatic parsing of the request body:

@PostMapping( path = "/feedback", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE}) public ResponseEntity handleNonBrowserSubmissions( @RequestParam MultiValueMap paramMap) throws Exception { // Save feedback data return new ResponseEntity("Thank you for submitting feedback", HttpStatus.OK); }

However, for a method parameter of type other than MultiValueMap, such as our Feedback domain object, we must use only the @RequestBody annotation.

5. Conclusion

Dans ce didacticiel, nous avons brièvement appris l'encodage des données de formulaire dans les formulaires Web. Nous avons également exploré comment gérer les données encodées en URL pour les requêtes HTTP de navigateur et non-navigateur en implémentant un formulaire de commentaires dans une application Web Spring Boot.

Comme toujours, le code source complet du didacticiel est disponible à l'adresse over sur GitHub.

REST bas

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS