Saturday, October 7, 2017

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

The Spring MVC framework, one of the most popular frameworks for developing a web application in Java world also provides several useful annotations to extract data from the incoming request and mapping the request to controller e.g. @RequestMapping, @RequestParam, and @PathVariable. Even though both @RequestParam and @ParthVariable is used to extract values from the HTTP request, there is a subtle difference between them, which makes them a useful question from interview and spring certification point of view. We'll examine the subtle difference between @RequestParam and @PathVaraible in this article. As the name suggests @RequestParam is used to get the request parameters from URL, also known as query parameters, while @PathVariable extracts values from URI.

For example, if the incoming HTTP request to retrieve a book on topic "Java" is http://localhost:8080/shop/order/1001/receipts?date=12-05-2017, then you can use the @RequestParam annotation to retrieve the query parameter date and you can use @PathVariable to extract the orderId i.e. "1001" as shown below:

@RequestMapping(value="/order/{orderId}/receipts", method = RequestMethod.GET)
public List listUsersInvoices(                               @PathVariable("orderId") int order,
 @RequestParam(value = "date", required = false) Date dateOrNull) {
...
}

The required=false denotes that query parameter can be optional but the URL must have the same URI.



How to extract Query Parameters in Spring MVC using @RequestParam

Spring MVC is a rich framework to develop both web applications and RESTful web services in Java. It provides several ways to retrieve data from the incoming HTTP requests e.g.
  • Request Parameters
  • Path Variables
  • Form inputs
Now that you know the difference between @RequestParam and @PathVariable in Spring MVC, let's see how to write Spring controllers that can handle request parameters and path variables.

Using @RequestParam to get Query parameters

In a Spring MVC application, you can use the @RequestParam annotation to accept query parameters in Controller's handler methods.

For examples, suppose you have a web application which returns details of orders and trades and you have following URLs:

http://localhost:8080/eportal/orders?id=1001

To accept the query parameters in the above URLs, you can use the following code in the Spring MVC controller:

@RequestMapping("/orders")
public String showOrderDetails(@RequestParam("id") String orderId, Model model){
   model.addAttribute("orderId", orderId);
   return "orderDetails";
}


If the name of the query parameter is same as the name of the variable in handler's @RequestParam annotated argument then you can simply use @RequestParam without specifying the name of a query parameter, Spring will automatically derive the value (see Introduction to Spring MVC).

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

Also, here is the code to prove the point:

URL: http://localhost:8080/eportal/trades?tradeId=2001

@RequestMapping("/trades")
public String showTradeDetails(@RequestParam String tradeId,
                               Model model){
  model.addAttribute("tradeId", tradeId);
  return "tradeDetails";
}

You can see that we have just annotated the method parameter tradeId with @RequestParam without specifying the name of the query parameter because the name of both request parameter and argument name is same i.e. "tradeId".

If you are interested in learning more about @RequestParam I suggest you checking out Introduction of Spring MVC 4 by Bryan Hassen to learn more about @RequestParam annotations.



Using @PathVariable annotation to extract values from URI

You can use Spring MVC's @PathVaraible annotation to extract any value which is embedded in the URL itself. Spring call it a URI template, where @PathVariable is used to obtain some placeholders from the URI itself.

If you have worked in RESTful Web services, you might know that the REST URIs contains values e.g. a REST API to retrieve a book using ISBN number looks like following:

URL: http://localhost:8080/book/9783827319333

Now, to extract the value of ISBN number from the URI in your Spring MVC Controller's handler method, you can use @PathVariable annotation as shown in following code:

@RequestMapping(value="/book/{ISBN}", method= RequestMethod.GET)
public String showBookDetails(@PathVariable("ISBN") String id,
                              Model model){
   model.addAttribute("ISBN", id);
   return "bookDetails";
}

Similar to @RequestParameter annotation, you also can also omit the value attribute in @PathVariable annotation, if the name of path variable's placeholder in the @RequestMapping annotation is same to the variable name in the handler method's @PathVariable annotated parameter (see REST with Spring).

For example, you can rewrite above code as shown below:

@RequestMapping(value="/book/{ISBN}", method= RequestMethod.GET)
public String showBookDetails(@PathVariable String ISBN, 
                              Model model){
   model.addAttribute("ISBN", ISBN);
   return "bookDetails";
}


Spring MVC provides several useful annotations to map and extract data from HTTP request and as Spring developer, you should be aware of these e.g. @RequestMapping, @RequestParam, and @PathVariable.

These concepts and annotations are very important from both Spring MVC interview prospect as well as Spring certifications. You will always find a couple of questions based upon these concepts.

Btw, if you are preparing for Spring Web Certifications, you can also check out David Mayer's free Spring Mock Questions to get an idea about the level of questions and format of questions you can expect on real Spring Web Certification.



Difference between @PathVariable and @RequestParam in Spring

Now that we understand both the difference as well as how to use both @RequestParam and @PathVariable in Spring MVC application, let's revise the key difference between them from an interview perspective.

1) The @RequestParam is used to extract query parameters while @PathVariable is used to extract data right from the URI.

2) @RequestParam is more useful on a traditional web application where data is mostly passed in the query abatements while @PathVariable is more suitable for RESTful web services where URL contains values e.g. http://localhost:8080/book/9783827319333, here data, which is ISBN number is part of URI.

If you want to learn more about how to effectively develop REST applications using Spring, I suggest you join Eugen Paraschiv's REST with Spring course.

It's an online course which will teach you the nitty-gritty of developing both REST API and services for real-world scenarios.

Eugen has extensive experienced in developing RESTful web services using Spring and this course is a great way to tap into his knowledge.

3) @RequestParam annotation can specify default values if query parameter is not present or empty by using a defaultValue attribute, provided required attribute is false.

4) Spring MVC allows you to use multiple @PathVariable annotations in the same method, provided, no more than one argument has the same pattern.


That's all about the difference between @PathVariable and @RequestParam in Spring MVC. Even though both are used to extract data from URL, @RequestParam is used to retrieve query parameters, anything after ? in the URL, while @PathVariable is used to retrieve values from URI itself.  This concept is very important for both traditional web application development as well as developing RESTful Web Services using Spring, so you must spend some time to understand it better.

Other Spring MVC articles you may like to explore
Introduction to Spring MVC 4 by Bryan Hassen
Difference between @RestController and @Controller in Spring MVC?
How Spring MVC works internally?
What is the use of DispatcherServlet in Spring MVC?
How to enable Spring security in a Java web application?
Spring in Action by Craig Walls

Thanks for reading this article so far. If you like this article then please share with your friends and colleagues. If you have any questions, please drop me a note. 

No comments :

Post a Comment