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
It 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.
@ImageSource-SlideShare.net
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.
Let’s discuss with a simple example – mapping an HTTP request to a method using some straightforward criteria.
@RequestMapping(value = "/doj/spring") @ResponseBody public String getDOJSpringCourse(){ return "Get DOJ Course for Spring"; }
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
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
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"; }
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.
Parts of the mapping URI can be bound to variables via the @PathVariable annotation.
@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; }
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
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
@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; }
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"; }
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"; }
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"; }
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; } }
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.
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…