Annotation Spring @Pathvariable

1. Vue d'ensemble

Dans ce rapide tutoriel, nous explorerons l' annotation @PathVariable de Spring .

En termes simples, l' annotation @PathVariable peut être utilisée pour gérer les variables de modèle dans le mappage d'URI de la requête et les utiliser comme paramètres de méthode.

Voyons comment utiliser @PathVariable et ses différents attributs.

2. Une cartographie simple

Un cas d'utilisation simple de l' annotation @PathVariable serait un point de terminaison qui identifie une entité avec une clé primaire:

@GetMapping("/api/employees/{id}") @ResponseBody public String getEmployeesById(@PathVariable String id) { return "ID: " + id; }

Dans cet exemple, nous utilisons l' annotation @PathVariable pour extraire la partie modélisée de l'URI représentée par la variable {id} .

Une simple requête GET à / api / Employees / {id} appellera getEmployeesById avec la valeur d'ID extraite:

//localhost:8080/api/employees/111 ---- ID: 111

Maintenant, explorons plus en détail cette annotation et examinons ses attributs.

3. Spécification du nom de la variable de chemin

Dans l'exemple précédent, nous avons ignoré la définition du nom de la variable de chemin du modèle car les noms du paramètre de méthode et de la variable de chemin étaient les mêmes.

Cependant, si le nom de la variable de chemin est différent, nous pouvons le spécifier dans l'argument de l' annotation @PathVariable :

@GetMapping("/api/employeeswithvariable/{id}") @ResponseBody public String getEmployeesByIdWithVariableName(@PathVariable("id") String employeeId) { return "ID: " + employeeId; }
//localhost:8080/api/employeeswithvariable/1 ---- ID: 1

Nous pouvons également définir le nom de la variable de chemin comme @PathVariable (valeur = "id") au lieu de PathVariable ("id") pour plus de clarté.

4. Plusieurs variables de chemin dans une seule demande

Selon le cas d'utilisation, nous pouvons avoir plus d'une variable de chemin dans notre URI de requête pour une méthode de contrôleur, qui a également plusieurs paramètres de méthode :

@GetMapping("/api/employees/{id}/{name}") @ResponseBody public String getEmployeesByIdAndName(@PathVariable String id, @PathVariable String name) { return "ID: " + id + ", name: " + name; }
//localhost:8080/api/employees/1/bar ---- ID: 1, name: bar

Nous pouvons également gérer plus d'un paramètre @PathVariable à l' aide d'un paramètre de méthode de type java.util.Map:

@GetMapping("/api/employeeswithmapvariable/{id}/{name}") @ResponseBody public String getEmployeesByIdAndNameWithMapVariable(@PathVariable Map pathVarsMap) { String id = pathVarsMap.get("id"); String name = pathVarsMap.get("name"); if (id != null && name != null) { return "ID: " + id + ", name: " + name; } else { return "Missing Parameters"; } }
//localhost:8080/api/employees/1/bar ---- ID: 1, name: bar

Il y a cependant un petit problème lors de la gestion de plusieurs paramètres @ PathVariable lorsque la chaîne de variable de chemin contient un caractère point (.). Nous avons discuté de ces cas de coin en détail ici.

5. Variables de chemin facultatives

Dans Spring, les paramètres de méthode annotés avec @PathVariable sont obligatoires par défaut:

@GetMapping(value = { "/api/employeeswithrequired", "/api/employeeswithrequired/{id}" }) @ResponseBody public String getEmployeesByIdWithRequired(@PathVariable String id) { return "ID: " + id; }

De par son apparence, le contrôleur ci-dessus doit gérer les chemins de requête / api / Employeeswithrequired et / api / Employeeswithrequired / 1 . Mais, comme les paramètres de méthode annotés par @PathVariables sont obligatoires par défaut, il ne gère pas les requêtes envoyées à / api / employés avec le chemin requis :

//localhost:8080/api/employeeswithrequired ---- {"timestamp":"2020-07-08T02:20:07.349+00:00","status":404,"error":"Not Found","message":"","path":"/api/employeeswithrequired"}  //localhost:8080/api/employeeswithrequired/1 ---- ID: 111

Nous pouvons gérer cela de deux manières.

5.1. Définition de @PathVariable comme non obligatoire

Nous pouvons définir la propriété requise de @PathVariable sur false pour la rendre facultative. Par conséquent, en modifiant notre exemple précédent, nous pouvons maintenant gérer les versions d'URI avec et sans la variable de chemin:

@GetMapping(value = { "/api/employeeswithrequiredfalse", "/api/employeeswithrequiredfalse/{id}" }) @ResponseBody public String getEmployeesByIdWithRequiredFalse(@PathVariable(required = false) String id) { if (id != null) { return "ID: " + id; } else { return "ID missing"; } }
//localhost:8080/api/employeeswithrequiredfalse ---- ID missing

5.2. Utilisation de java.util.Optional

Depuis Spring 4.1, nous pouvons également utiliser java.util.Optional (disponible dans Java 8+) pour gérer une variable de chemin non obligatoire:

@GetMapping(value = { "/api/employeeswithoptional", "/api/employeeswithoptional/{id}" }) @ResponseBody public String getEmployeesByIdWithOptional(@PathVariable Optional id) { if (id.isPresent()) { return "ID: " + id.get(); } else { return "ID missing"; } }

Maintenant, si nous ne spécifions pas la variable de chemin id dans la requête, nous obtenons la réponse par défaut:

//localhost:8080/api/employeeswithoptional ---- ID missing 

5.3. Utilisation d'un paramètre de méthode de type map

Comme indiqué précédemment, nous pouvons utiliser un paramètre de méthode unique de type java.util.Map pour gérer toutes les variables de chemin dans l'URI de la requête. Nous pouvons également utiliser cette stratégie pour gérer le cas des variables de chemin optionnelles:

@GetMapping(value = { "/api/employeeswithmap/{id}", "/api/employeeswithmap" }) @ResponseBody public String getEmployeesByIdWithMap(@PathVariable Map pathVarsMap) { String id = pathVarsMap.get("id"); if (id != null) { return "ID: " + id; } else { return "ID missing"; } }

6. Valeur par défaut pour @PathVariable

Out of the box, there isn't a provision to define a default value for method parameters annotated with @PathVariable. However, we can use the same strategies discussed above to satisfy the default value case for @PathVariable. We just need to check for null on the path variable.

For instance, using java.util.Optional, we can identify if the path variable is null or not. If it is null then we can just respond to the request with a default value:

@GetMapping(value = { "/api/defaultemployeeswithoptional", "/api/defaultemployeeswithoptional/{id}" }) @ResponseBody public String getDefaultEmployeesByIdWithOptional(@PathVariable Optional id) { if (id.isPresent()) { return "ID: " + id.get(); } else { return "ID: Default Employee"; } }

7. Conclusion

Dans cet article, nous avons expliqué comment utiliser l' annotation @PathVariable de Spring . Nous avons également identifié les différentes façons d'utiliser efficacement l' annotation @PathVariable pour répondre à différents cas d'utilisation tels que les paramètres facultatifs et le traitement des valeurs par défaut.

L'exemple de code présenté dans cet article est également disponible à l'adresse over sur Github.