Sometimes we want to send values to our web application as the path of the URL (or URI) path. For example, /tenants/123 where value 123 represents a tenant Id. To independently access the value in Spring MVC, we use the PathVariable annotation.
In this post, we are using Spring 5.
PathVariable Annotation Lets Us Pick Part of an URL as the value
How does the Spring MVC PathVariable annotation enable us to pick a part of an URL as a value? To use the PathVariable annotation, we need to work closely with some annotations – RequestMapping or XXMapping (GetMapping, PostMapping, etc.).
Consider the following example where we use a named placeholder – {id} – in the URI. Spring automatically ties up the placeholder with the variable name id, which also uses the PathVariable annotation.
1 2 3 4 | @GetMapping("/api/tenants/{id}") public Tenant getTenantById(@PathVariable String id) { //… } |
But we do not want to do that! If someone changes the parameter variable id to something else, the code will not work. A safer approach is to use the placeholder’s name as an argument to the PathVariable annotation. Consider the following code example.
1 2 3 4 | @GetMapping("/api/tenants/{id}") public Tenant getTenantById(@PathVariable(“id”) String tenantId) { // … } |
More Advanced Mappings in Spring MVC with PathVariable
The codes we showed in the previous section are for methods. What if we extract a path value from a URL we placed on the class level? Consider the following.
1 2 3 4 5 6 7 8 9 10 | @RestController @RequestMapping("/api/persons/{personId}") public class PersonController { @GetMapping("/pets/{petId}") public Pet getPetById(@PathVariable(“personId”) String id, @PathVariable(“petId”) String petId) { //… } } |
Notice that we are also using multiple PathVariable annotations to access the values for personId and petId.
Uncommon Mapping Styles with Spring MVC PathVariable
If we do not want to use multiple PathVariable annotations in our controller, we capture the values as Map. However, this may restrict us to using a single type for the values, e.g., Map<String, String>.
Consider the following codes.
1 2 3 4 5 6 | @GetMapping("/api/persons/{personId}/pets/{petId}") public String getPetById(@PathVariable Map<String, Long> map) { Long personId = map.get("personId"); Long petId = map.get("petId"); //… } |
Lastly, we can use regular expressions with the PathVariable annotation in Spring MVC. Consider the following example.
1 2 3 4 5 6 | @GetMapping("/api/transactions/{year:\\d{4}}-{month:\\d{2}-{date:\\d{2)}") public List<Report> getReportsByDate(@PathVariable("year”) Long year, @PathVariable(“month”) Long month, @PathVariable(“date”) Long date) { //… } |
In the code example, we essentially split a port of the URL into the year, month, and date values.