Spring @RequestMapping Annotation Example with @RequestParam, @PathVariable

Spring @RequestMapping Annotation Example with @RequestParam, @PathVariable

In this article, we are going discuss about one of the main annotation in Spring MVC @RequestMapping – used to mapping a web request to Spring Controller's handler methods.

All incoming requests are handled by the Dispatcher Servlet and it route them through Spring. When it receives a web request, it determines which controllers should handle the incoming request.

Dispatcher Servlet initially scans all the classes that are annotated with the @Controller annotation. The dispatching process depends on the various @RequestMapping annotations declared in a controller class and its handler methods.
There are three levels of request mapping in Spring MVC
  • @RequestMapping annotations at only method level
  • @RequestMapping annotations at class level
  • Mapping requests by request type

@RequestMapping can be applied to the controller class as well as methods. This annotation for mapping web requests onto specific handler classes and/or handler methods.

Spring MVC RequestMapping Annotation
@ImageSource-SlideShare.net
@RequestMapping annotations at only method level
In this case we are using @RequestMapping annotations is to declare the handler methods directly. The handler method is annotated with @RequestMapping annotation containing a URL pattern. If this pattern of a handler @RequestMapping annotation matches the request URL, DispatcherServlet it dispatches the request to this handler for it to process the request.
1. @RequestMapping Basics

Let’s discuss with a simple example – mapping an HTTP request to a method using some straightforward criteria.

1.1 @RequestMapping – by Path

@RequestMapping(value = "/doj/spring")
 @ResponseBody
 public String getDOJSpringCourse(){
    return "Get DOJ Course for Spring";
 }
Popular Tutorials
Spring Tutorial Spring MVC Web Tutorial Spring Boot Tutorial
Spring Security Tutorial Spring AOP Tutorial Spring JDBC Tutorial
Spring HATEOAS Microservices with Spring Boot REST Webservice
Core Java Hibernate Tutorial Spring Batch
For testing hit following URL on browser:

GET http://localhost:8080/SpringApp/doj/spring

-- response --
200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html
Content-Length: 25
Date: Fri, 18 Mar 2016 10:38:14 GMT

Get DOJ Course for Spring


1.2  @RequestMapping – the HTTP Method

There is no by default HTTP method mapped by a @RequestMapping – so it maps to any type of HTTP request; we sh to add the method :

@RequestMapping(value = "/doj/spring", method = RequestMethod.POST)
 @ResponseBody
 public String postDOJSpringCourse(){
  return "Post DOJ Course for Spring";
 }

POST http://localhost:8080/SpringApp/doj/spring
Content-Type: application/json

-- response --
200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html
Content-Length: 26
Date: Fri, 18 Mar 2016 10:38:22 GMT

Post DOJ Course for Spring

2. RequestMapping with HTTP Headers

2.1. @RequestMapping with the headers attribute

The mapping can be narrowed even further by specifying a header for the request:

@RequestMapping(value = "/doj/spring", headers = "key=val")
 @ResponseBody
 public String getDOJSpringCourseWithHeaders(){
  return "Get DOJ Course for Spring with headers";
 }

And even multiple headers via the header attribute of @RequestMapping:

@RequestMapping(value = "/doj/spring", headers = {"key1=val1", "key2=val2"})
 @ResponseBody
 public String getDOJSpringCourseWithHeaders(){
  return "Get DOJ Course for Spring with headers";
 }

2.2. @RequestMapping Consumes and Produces

Mapping media types produced by a controller method is worth special attention – we can map a request based on its Accept header via the @RequestMapping headers attribute introduced above:

@RequestMapping(value = "/doj/spring", headers = "Accept=application/json")
 @ResponseBody
 public String getDOJSpringCourseJSON(){
  return "Get DOJ Course for Spring as JSON";
 }

GET http://localhost:8080/SpringApp/doj/spring
key: value

-- response --
200 OK
Server: Apache-Coyote/1.1
Content-Type: application/json
Content-Length: 33
Date: Fri, 18 Mar 2016 10:57:03 GMT

Get DOJ Course for Spring as JSON

@RequestMapping annotation now has a produces and a consumes attributes, specifically for this purpose:

@RequestMapping(value = "/doj/spring", method = RequestMethod.GET, produces = "application/json")
 @ResponseBody
 public String getDOJSpringCourseJSONFromREST(){
  return "Get DOJ Course for Spring as JSON from REST";
 }

GET http://localhost:8080/SpringApp/doj/spring
key: value

-- response --
200 OK
Server: Apache-Coyote/1.1
Content-Type: application/json
Content-Length: 43
Date: Fri, 18 Mar 2016 11:00:28 GMT

Get DOJ Course for Spring as JSON from REST

Additionally, produces support multiple values as well:
@RequestMapping(value = "/doj/spring", produces = { "application/json", "application/xml" })

A final note on the new produces and consumes mechanism – these behave differently from most other annotations: when specified at type level, the method level annotations do not complement but override the type level information.

3. RequestMapping with Path Variables

Parts of the mapping URI can be bound to variables via the @PathVariable annotation.

3.1. Single @PathVariable

@RequestMapping(value = "/doj/spring/{id}")
 @ResponseBody
 public String getDOJCourseWithPathVariable(@PathVariable("id") int id) {
    return "Get a DOJ Course with id=" + id;
 }

GET http://localhost:8080/SpringApp/doj/spring/2000

-- response --
200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html
Content-Length: 29
Date: Fri, 18 Mar 2016 11:11:40 GMT

Get a DOJ Course with id=2000

If the name of the method argument matches the name of the path variable exactly, then this can be simplified by using @PathVariable with no value:

@RequestMapping(value = "/doj/spring/{id}")
 @ResponseBody
 public String getDOJCourseWithPathVariable(@PathVariable int id) {
    return "Get a DOJ Course with id=" + id;
 }

3.2. Multiple @PathVariable

More complex URI may need to map multiple parts of the URI to multiple values:

@RequestMapping(value = "/doj/{course}/{id}")
 @ResponseBody
 public String getDOJCourseWithPathVariable(@PathVariable("course") String course ,@PathVariable("id") long id) {
    return "Get a DOJ Course with id=" + id+" course name ="+course;
 }

GET http://localhost:8080/SpringApp/doj/spring/2000

-- response --
200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html
Content-Length: 49
Date: Fri, 18 Mar 2016 11:16:19 GMT

Get a DOJ Course with id=2000 course name =spring

3.3. @PathVariable with RegEx

Regular expressions can also be used when mapping the @PathVariable; for example, we will restrict the mapping to only accept numerical values for the id:

@RequestMapping(value = "/doj/{course}/{numericId:[\\d]+")
 @ResponseBody
 public String getDOJCourseWithPathVariable(@PathVariable("course") String course ,@PathVariable("id") long id) {
    return "Get a DOJ Course with id=" + id+" course name ="+course;
 }

This will mean that the following URIs will match:
http://localhost:8080/SpringApp/doj/spring/2000

But this will not:
http://localhost:8080/SpringApp/doj/spring/xyz

4. RequestMapping with Request Parameters

@RequestMapping allows easy mapping of URL parameters with the @RequestParam annotation.

We are now mapping a request to an URI such as:

@RequestMapping(value = "/doj/spring")
 @ResponseBody
 public String getDOJCourseByRequestParam(@RequestParam("id") long id) {
     return "Get a DOJ Course with id=" + id;
 }

We are then extracting the value of the id parameter using the @RequestParam(“id”) annotation in the controller method signature.

GET http://localhost:8080/SpringApp/doj/spring?id=2000

-- response --
200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html
Content-Length: 29
Date: Fri, 18 Mar 2016 11:29:25 GMT

Get a DOJ Course with id=2000

@RequestMapping can optionally define the parameters – as yet another way of narrowing the request mapping:

@RequestMapping(value = "/doj/spring", params = "id")
 @ResponseBody
 public String getDOJCourseByRequestParam(@RequestParam("id") long id) {
     return "Get a DOJ Course with id=" + id;
 }


Even more flexible mappings are allowed – multiple params values can be defined, and not all of them have to be used:

@RequestMapping(value = "/doj/spring", params = {"id","course"})
 @ResponseBody
 public String getDOJCourseByRequestParam(@RequestParam("id") long id, @RequestParam("course") String course) {
     return "Get a DOJ Course with id=" + id+" Course="+course;
 }

5. RequestMapping Corner Cases

5.1. @RequestMapping – multiple paths mapped to the same controller method

Although a single @RequestMapping path value is usually used for a single controller method, this is just good practice, not a hard and fast rule – there are some cases where mapping multiple requests to the same method may be necessary. For that case, the value attribute of @RequestMapping does accept multiple mappings, not just a single one:

@RequestMapping(value = {"/doj/spring/index", "/doj/spring/home"})
 @ResponseBody
 public String getDOJHome() {
     return "Get a DOJ Home Page";
 }

5.2. @RequestMapping – multiple HTTP request methods to the same controller method

Multiple requests using different HTTP verbs can be mapped to the same controller method:

@RequestMapping(value = {"/doj/spring/home"}, method = {RequestMethod.GET, RequestMethod.POST})
 @ResponseBody
 public String getDOJHome() {
     return "Get a DOJ Home Page";
 }
  

5.3. @RequestMapping – a fallback for all requests

To implement a simple fallback for all requests using a specific HTTP method:

@RequestMapping(value = {"*"})
 @ResponseBody
 public String getDOJDefaultPage() {
     return "Get a DOJ Default Page";
 }
  

@RequestMapping annotations at class level
In this case we are using @RequestMapping annotations at the class level. It is used for filter all incoming request at class level first before forwarding to handler methods. If the incoming request matches the pattern defined in controller class, then it search the controller methods mappings.
@Controller
@RequestMapping("/login/")
public class Login{

 @RequestMapping("doLogin")
 public ModelAndView doLogin(
   @RequestParam(value = "username") String username,
   @RequestParam(value = "password") String password) {
  //....
  //....
  return null;
 }
 
 @RequestMapping(value={"logout","signout"})
 public ModelAndView logout(
   @RequestParam(value = "username") String username) {
  //....
  //....
  
  return null;
 } 
}
  
Conclusion

This article focus on the @RequestMapping annotation in Spring – discussing a simple usecase, the mapping of HTTP headers, binding parts of the URI with @PathVariable and working with URI parameters and the @RequestParam annotation.



Labels: , , ,