Tuesday, December 12, 2017

Differences between @RequestParam and @PathVariable annotations in Spring MVC?

Have you came across @RequestParam & @PathVariable annotation used in the Spring MVC framework? If your answer is yes, then do you know exactly when, one should use @RequestParam or @PathVariable annotation because both the annotations are used to extract data from the incoming request. If your answer is no, then you must learn/know about these annotations because it's widely used in both the traditional web application development & RESTful Web Services development using Spring.

Table Of Content

1. Introduction
2. Scope
3. When to use which annotations?
4. Where and How of annotations?
5. Conclusion


1. Introduction


Both the annotations @RequestParam & @PathVariable are used to fetch the data from incoming request but with a little difference and that's what we are going to found out.

2. Scope


We would discuss when, where & How of the @RequestParam or @PathVariable annotations.

3. When to use which annotations?


We would understand the exact use case when to use @RequestParam or @PathVariable annotations by an example. It won't take more than 2 minutes. Let's analyze the below URL:
//return all the books issued to a user ('userId': 21) on 'December 11th, 2017'
http://localhost:8080/elibrary/user/21/books?date=11-12-2017
Let's divide the above URL in two parts:
  1. http://localhost:8080/elibrary/user/21/books
    Here, the variable part i.e. 'userId' is also called URI template variable. To fetch values from a URL path variable/URI template variable, we would use @PathVariable annotation. If one omits this path variable the it would change the URL and it may happen that it won't work at all. 
  2. ?date=11-12-2017
    These key value pairs appended after '?' of a URL are also called request parameters or query parameters. To fetch values from a query parameters, we would use @RequestParam annotation. If someone omits these query parameter then it might not break the application, in this case it will return all books issued to a user irrespective of date. 
I hope, now it pretty much clear that when to use which annotation.

4. Where & How of annotations?


Both the annotations i.e. @RequestParam & @PathVariable are used inside the controller, on a method argument to bind it to the value of a query parameters & URI template variables respectively.
  • @RequestParam to extract values from Query parameters
    @RequestParam annotation is used to bind request parameters to a method argument in the controller.
    Suppose we have a web application which returns the details of all the books in the search results when a user search with the full/partial ISBN & we have respective data in the database.
    http://localhost:8080/search?searchbox=978
    
    @GetMapping(value = "/search")
    @PreAuthorize("isAuthenticated()")
    public String search(@RequestParam(value = "searchbox") String query, Model model) {
       query = query.replaceAll("\\\\", "").replaceAll("_", "").replaceAll("%", ""); // "\\\\_%%" => "Geoactive"
       query = StringEscapeUtils.escapeSql(query); // only turns single-quotes into doubled single-quotes ("McHale's Navy" => "McHale''s Navy")
       query = "%" + query + "%";
    
       //Make service call to check if the data is vailable in the database or not 
      
       if (data is not available) {
         model.addAttribute("error", "Try Again!! Using some other ISBN");
       } else {
         model.addAttribute("books", listOfBooksObj);
        }
       return "serch-results";
    }
    
    Some important pointers:
    • If the name of the method argument matches the name of the query parameter variable exactly, then one can directly use @RequestParam with no value like
      http://localhost:8080/search?searchbox=978
      public String search(@RequestParam String searchbox, Model model) {
      ...}
      
    • Method parameters using this annotation are required by default, but one can specify that a parameter is optional by setting @RequestParam's required attribute to false (e.g., @RequestParam(value="id", required=false)).
    • Type conversion is applied automatically if the target method parameter type is not String.
  • @PathVariable to extract values from URI template variable
    @PathVariable annotation is used to bind a URI template variable to a method argument in the controller.
    http://localhost:8080/order/22
    
    @RequestMapping(value="/order/{orderId}", method= RequestMethod.GET)
    public String showBookDetails(@PathVariable(value="orderId") String id, Model model){
       //service call to get the Order object by orderkId
       model.addAttribute("order", orderObject);
       return "orderDetails";
    }
    
Similar to @RequestParameter annotation, one can also omit the value attribute in @PathVariable annotation, if the name of method argument exactly matches the name of the URI template variable.

5. Conclusion


Both the annotations @RequestParam and @PathVariable are very useful while developing traditional web application and RESTful web services. Now we know, which annotation to use to fetch query parameter value or URI template variable value.

Thank you for reading this article. Feel free to connect with me for any queries and suggestions. See you soon. Happy Learning !!

Reference

No comments:

Post a Comment