Thursday, April 11, 2024

10 Examples of @RequestMapping Annotation in Spring MVC and REST

The @RequestMapping annotation is one of the most important annotation of Spring MVC which provides mapping of HTTP requests to controller methods, I mean Java methods on Controller class for processing. If you wonder, how Spring handles a particular request and which method from controller class is called for a particular request, answer lies on @RequestMapping annotation. This annotation maps web request to methods on controller class. You can apply @RequestMapping on class or method level of your controller. This is a powerful annotation and give you a lot of option to sophistically map a web request e.g. you can narrow down mapping by using HTTP headers, HTTP methods e.g. PUT or POST, and by using Query parameters.

 In this article, I'll share some of the useful examples of using @RequestMapping annotation in your Spring MVC application.  This was also one of the Spring MVC annotation I discussed earlier on 10 Essential Spring MVC annotations article, if you haven't read, you can also read that to get yourself up-to-speed on spring MVC. 


10 Example of @RequestMapping Annotation in Java

If you are developing RESTful web services using Spring MVC then just annotated the method with @ResponseBody or annotated the whole Controller with @RestController annotation. It will take care of automatically writing response to HTTP response body instead of returning a logical view name. 

1. @RequestMapping by Class

One of the simplest example of @RequestMapping annotation is to apply it on type level for base URL and then annotate method with more specific URLs e.g. @RequestMapping("/home" ) will map to/home URL, applies to all HTTP methods

Btw, its important o know that methods without request mapping will be ignored even when @RequestMapping is on a class level.

2. @RequestMapping by HTTP methods

You can also map request to a method based upon which HTTP method is used to send request like GET or POST. For example, @RequestMapping(value="/foo" ,method=RequestMethod.POST) - Maps to /foo URL, but only HTTP POST method

3. @RequestMapping by Request or Query Parameters

The @RequestMapping annotation also allow you to map a request to a Java method in Controller class by using Query parameters. For example, @RequestMapping(value="/foo", params={"bar"}) - Maps to /foo URL but only when foo and bar params are included with any value (/foo?bar=something). You can also  provide multiple parameters.

10 Examples of @RequestMapping Annotation in Spring MVC and REST


4) @RequestMapping by Query Parameter with Specific Value

Not just Query parameter, you can also map a request to a particular Java method based upon a specific value supplied in Query parameter in Spring MVC. For example, @RequestMapping(value="/foo" , params={ "bar=baz"}) - maps to /foo URL but only when bar parameter is provided with a value of 'baz'


5) @RequestMapping with class and method level

You can also do request mapping at the class and method level using @RequestMapping parameters on Spring MVC. For example, @RequestMapping("/foo") on class level and @RequestMapping("/bar") on a method level results in mapping to URL /foo/bar


6) @RequestMapping and HTTP Headers

The mapping can be narrowed even further by specifying an HTTP header for the request as shown in following example:

@RequestMapping(value = "/ex/foos", headers = "key=val", method = GET)
@ResponseBody
public String getFoosWithHeader() {
   return "Get some Foos with Header";
}

7) @RequestMapping by multiple HTTP header values

You can also map requests based upon multiple HTTP header values and @RequestMapping also allows you to combine header values as shown in following example:
@RequestMapping(
value = "/ex/foos", 
headers = { "key1=val1", "key2=val2" }, method = GET)
@ResponseBody
public String getFoosWithHeaders() {
  return "Get some Foos with Header";
}

8) @RequestMapping with ContentType

You can also perform request mapping based upon the ContentType header in Spring MVC. Starting with Spring 3.1, the @RequestMapping annotation now has the produces and the consumes attributes, specifically for this purpose. 

@RequestMapping(
value = "/ex/foos", 
method = RequestMethod.GET, 
produces = "application/json"
)
@ResponseBody
public String getFoosAsJsonFromREST() {
  return "Get some Foos with Header New";
}

In earlier version of Spring you could have used "Accept" header to map a web request to a controller method by media type e.g.

@RequestMapping(
value = "/ex/foos", 
method = GET, 
headers = "Accept=application/json")
@ResponseBody
public String getFoosAsJsonFromBrowser() {
return "Get some Foos with Header Old";
}

One important thing to note is that when you define produces and consumes attribute at both class and method level then the method level annotations do not complement but override the type level information

If you want to learn more about content type mapping while developing RESTful Web Services using Spring, you can further check out REST with Spring course by Eugen.


9) Request Mapping using Path Variables

You can also use @RequestMapping and @PathVariable together to map a web request to a method in controller. This is one of the powerful way of request mapping in Spring. 

Here is a simple example with a single path variable:
@RequestMapping(value = "/ex/foos/{id}", method = GET)
@ResponseBody
public String getFoosBySimplePathWithPathVariable(
@PathVariable("id") long id) {
  return "Get a specific Foo with id=" + id;
}

Also, If the name of the method argument is same as the path variable then you don't need to provide value attribute to @PathVariable as shown below:
@RequestMapping(value = "/ex/foos/{id}", method = GET)
@ResponseBody
public String getFoosBySimplePathWithPathVariable(
@PathVariable String id) {
  return "Get a specific Foo with id=" + id;
}

Also, @PathVariable benefits from automatic type conversion, which means you could have declared id parameter as long and Spring would have converted it from String to long. See Introduction to Spring MVC  courses for more details on request mapping using @PathVariable

10)@RequestMapping and multiple @PathVariable 

You can also map a web request to a controller method in Spring MVC by using multiple @PathVariable

More complex URI may need to map multiple parts of the URI to multiple values:
@RequestMapping(value = "/ex/foos/{fooid}/bar/{barid}", method = GET)
@ResponseBody
public String getFoosBySimplePathWithPathVariables
(@PathVariable long fooid, @PathVariable long barid) {
  return "Get a specific Bar with id=" + barid + 
           " from a Foo with id=" + fooid;
}

11) Mapping multiple request to Single method (Bonus)

Even though its not ideal to map multiple web request to single method, sometimes its necessary and thankfully Spring MVC allows you to map multiple URLs to single controller method by providing multiple mapping to @RequestMapping annotation as shown below:

@RequestMapping(
value = { "/contact", "/about" }, 
method = GET)
@ResponseBody
public String getContactOrAbout() {
  return "java@gmail.com";
}

You can test this using curl command in Linus, both request to about and contact will go to the same method i.e.

$ curl -i https://localhost:8080/spring-mvc/about
$ curl -i https://localhost:8080/spring-mvc/contact

will hit the same getContactOrAbout() method. 


Important Points about @RequestMapping Annotation in Spring MVC

Here are some of the most important points about @ReuqestMapping annotation of Spring MVC framework, which are worth remembering:

1)The @RequestMapping annotation was introduced on Spring 2.5 version.  So, its not available on Spring 1.0 and earlier version. 

2)The @RequestMapping annotation can be applied on class level or method level of a Spring MVC Controller e.g. a class annotated with @Controller annotation.

3)The @RequestMapping("/home" ) maps to /home URLs, applies to all HTTP methods e.g. GET, POST or PUT. 

3) The @RequestMapping(value="/home" ,method=RequestMethod.POST) maps to /home URL, but only HTTP POST method i.e. the method with above annotation will only be invoked when a HTTP POST request will hit the /home URL. 

4) The @RequestMapping(value="/stock", params={"exchange"}) maps to /stock URL but only when exchange query parameters is included with any value e.g. /stock?exchange=NYSE. You can even provide multiple query parameters.


5) The @RequestMapping(value="/stock" , params={ "exchange=NYSE"}) maps to /stock URL but only when exchange request parameter is provided with a value of 'NYSE'.

6) One of the important thing to remember is that methods without @RequestMapping annotation are ignored even when @RequestMapping is applied on a class level. 

7) The @RequestMapping("/home") on class level and @RequestMapping("/course") on a method level results in mapping to URL /home/course

8) You can also narrow down request mapping by using header attributes of @RequestMapping e.g. @RequestMapping(value = "/home", headers = "Accept=application/json", method = GET) will only be called when GET request at /home will be called using header key with specified value. You can even specify multiple headers e.g. "Accept:application/json" and "Accept:application/xml" for more sophisticated mapping. 

9) You can also use @PathVariable along with @RequestMapping annotation to extract data from URI e.g. @RequestMapping(value = "/book/{ISBN}", method = GET), here ISBN can be extracted using @PathVariable annotation. 

10) You can even map a single method to multiple request by providing multiple mapping to the @RequestMapping annotation e.g. @RequestMapping( value = { "/contact", "/about" }, method = GET) will map to both /contact and /about URLs.

That's all about @RequestMapping annotation in Spring MVC. It is one of the most important annotation of Spring MVC framework, even more important than @Controller because @Controller is just a stereotype annotation, it doesn't matter if you annotate the class with @Component or @Controller because all the hard work of request mapping to controller methods is done by @RequestMapping. It can be applied at class level or method level and gives you powerful option to sophistically control the mapping of request using HTTP headers, HTTP methods and Query parameters. 

Further Reading
Spring Fundamentals
Introducing Spring MVC 
Spring in Action book

Other Spring Framework articles you may like to explore 

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 or suggestions then please let me know. If you have to add any other example of @RequestMapping, which is missing in this list, feel free to add.

1 comment:

  1. what is the meaning of controller class? How does Spring MVC find to route a particular request to particular class? I know in Servlet we had this thing called URL Mapping which maps certain URL to certain servlet but how does it work in spring Mvc?

    ReplyDelete