Just like @RequestParam, @PathVariable annotation is used to extract data from HTTP request . However, they differ slightly. The difference is that @RequestParam gets parameters from the URL while @PathVariable simply extracts them from the URI.
Example
Let’s imagine you had a website that supported the following URL:
http://www.yourwebsite.net/employee/1
1 in the URL above represents the ID of the employee. So far so good. Now however, from your Spring controller, the path would look like (depending upon the name you give to the id):
/employee/{id}
How does the above URL path help us? Well, because of that { } syntax (which happens to be called URI template), you can now pass this to a method using @PathVariable and your method, along with the annotations, will look similar to the following:
@RequestMapping(value="/employee/{id}", method=RequestMethod.GET) <Access Modifier> <Return Type> <Method Name> (@PathVariable <Type> id) { <body> }
As you can see from the code snippet above, now “id” will reference {id} from the path. Let’s try out with a real example:
@Controller @SpringBootApplication public class EmployeeManager { @RequestMapping(value=" /employee/{id}") public String pathVariableDemo(Model model, @PathVariable int id) { model.addAttribute("id", id); return "demo"; } }
Now, Spring looks at out id parameter and matches it up with the template variable “id”.
Keep in mind that if my code had “id” (the parameter) named to something else it wouldn’t work. However, in case you don’t want to use the same names for both the parameter and the template variable, you can specify the name of the PathVariable annotation like so:
@Controller @SpringBootApplication public class EmployeeManager { @RequestMapping(value=" /employee/{id}") public String pathVariableDemo(Model model, @PathVariable("id") int someRandomName) { model.addAttribute("id", someRandomName); return "demo"; } }
As you can see from the example above, I changed the parameter’s name to someRandomName but I also added @PathVariable(“id”) which, again, specifies which template variable we are reffering to.
So in the end you got two options:
- Use the same name for the method parameter
- Specify the name of the template variable in the @PathVariable annotation
Multiple @PathVariable annotation
What if you could have multiple @PathVariable’s? Can we do it? Yes we can! In fact, it’s pretty similar to adding a single @PathVariable.
Let me show you.
@Controller @SpringBootApplication public class EmployeeManager { @RequestMapping(value="/{company}/employee/{id}", method=RequestMethod.GET) public String pathVariableDemo(@PathVariable("company") String companyName, @PathVariable("id") int employeeId) { // handle the code return "demo"; } }
As you can see from the code snippet above, we have two template variables:
- company
- id
Then, we extracted each template variable and “assigned” them to method parameters by specifying which tempalte variable the method parameter is refering to.
@PathVariable vs @RequestParam conclusion
Although both @PathVariable and @RequestParam are used to extract values from the URL, they can be used depending on the design of the URL.
In general, @PathVariable is mostly used in RESTful web services while @RequestParam is used to extract data from query parameters.