RequestMapping is one of the most commonly used annotations in Spring Web applications. This annotation maps the HTTP request to the MVC and REST controller handling methods.

In this article, you’ll see how the @RequestMapping annotation can be versatile when used to map Spring MVC controller methods.

Request Mapping basic usage

In a Spring MVC application, the RequestDispatcher (below the Front Controller) servlet is responsible for routing incoming HTTP requests to the Controller’s processing methods.

When configuring Spring MVC, you need to specify the mapping between requests and handling methods.

To configure the mapping for Web requests, you need to use the @requestMapping annotation.

The @RequestMapping annotation can be used at the level of the controller class and/or the methods within it.

Annotations at the class level map a specific request or request pattern to a controller. You can then add additional method-level annotations to further specify the mapping to the processing methods.


leoxu

Here is an example of applying the @requestMapping annotation to both a class and a method:

@RestController @RequestMapping("/home ") public class IndexController { @RequestMapping("/ ") String get() { //mapped to hostname:port/home/ return "Hello from get "; } @RequestMapping("/index ") String index() { //mapped to hostname:port/home/index/ return "Hello from index "; }}Copy the code

As shown in the code above, requests to /home are handled by the get() method, and requests to /home/index are handled by index().

RequestMapping to handle multiple URIs

You can map multiple requests to a method by adding a @requestMapping annotation with a list of request path values.

@RestController @RequestMapping("/home ") public class IndexController { @RequestMapping(value = { " ", "/page ", "page* ", "view/*,**/msg " }) String indexMultipleMapping() { return "Hello from index multiple mapping. "; }}Copy the code

As you can see in this code, @RequestMapping supports wildcards as well as ANT style paths. In the previous code, the following urls are handled by indexMultipleMapping() :

  • localhost:8080/home

  • localhost:8080/home/

  • localhost:8080/home/page

  • localhost:8080/home/pageabc

  • localhost:8080/home/view/

  • localhost:8080/home/view/view


leoxu

@requestMapping with @requestParam

The @requestParam annotation is used in conjunction with @RequestMapping to bind the parameters of the request to the parameters of the processing method.

The @requestParam annotation can be used with or without a value. This value specifies the request parameters that need to be mapped to the processing method parameters, as shown below:

@RestController @RequestMapping("/home ") public class IndexController { @RequestMapping(value = "/id ") String getIdByValue(@RequestParam("id ") String personId) { System.out.println("ID is " + personId); return "Get ID from query string of URL with value element "; } @RequestMapping(value = "/personId ") String getId(@RequestParam String personId) { System.out.println("ID is " + personId); return "Get ID from query string of URL without value element "; }}Copy the code

In line 6, the id request parameter is mapped to the personId parameter of the thegetIdByValue() handler.

If the request parameter has the same name as the handler parameter, the @requestParam annotation value parameter can be omitted, as shown in line 11 of the code.

The required parameter of the @requestParam annotation defines whether the parameter value must be passed.

@RestController @RequestMapping("/home ") public class IndexController { @RequestMapping(value = "/name ") String getName(@RequestParam(value = "person ", required = false) String personName) { return "Required element of request param "; }}Copy the code


leoxu

In this code, since required is specified as false, the getName() method handles both urls:

  • /home/name? person=xyz

  • /home/name

The @requestparam defaultValue value is used to provide a defaultValue for a null request parameter.

@RestController @RequestMapping("/home ") public class IndexController { @RequestMapping(value = "/name ") String getName(@RequestParam(value = "person ", defaultValue = "John ") String personName) { return "Required element of request param "; }}Copy the code

In this code, if the person request parameter is null, the getName() handler receives the default value John as its argument.


leoxu

Handle various HTTP methods using @requestMapping

Spring MVC’s @RequestMapping annotation can handle HTTP request methods such as GET, PUT, POST, DELETE, and PATCH.

All requests will default to HTTP GET.

In order to map a request down to a specific HTTP method, you need to declare the method type used in the HTTP request using method in @requestMapping, as follows:

@RestController @RequestMapping("/home ") public class IndexController { @RequestMapping(method = RequestMethod.GET) String get() { return "Hello from get "; } @RequestMapping(method = RequestMethod.DELETE) String delete() { return "Hello from delete "; } @RequestMapping(method = RequestMethod.POST) String post() { return "Hello from post "; } @RequestMapping(method = RequestMethod.PUT) String put() { return "Hello from put "; } @RequestMapping(method = RequestMethod.PATCH) String patch() { return "Hello from patch "; }}Copy the code

In this code, the method element in the @RequestMapping annotation declares the HTTP method type for the HTTP request.

All processing methods will handle requests coming from the same URL(/home), but it depends on what HTTP method is specified to determine which method to use.

For example, a POST request /home is handled by the POST () method, and a DELETE request /home is handled by the DELETE () method.

You’ll see that Spring MVC will use this same logic to map other methods.


leoxu

Use @requestMapping to handle production and consumption objects

You can use the produces and Consumes elements of the @requestMapping annotation to narrow down the types of mapping requests.

To produce an object using the requested media type, you use the @requestMapping produces element in conjunction with the @responseBody annotation.

You can also use the comSumes element of @RequestMapping in conjunction with the @RequestBody annotation to consume objects with the requested media type.

The following code uses the @requestMapping production and consumption object elements:

@RestController @RequestMapping("/home ") public class IndexController { @RequestMapping(value = "/prod ", produces = { "application/JSON " }) @ResponseBody String getProduces() { return "Produces attribute "; } @RequestMapping(value = "/cons ", consumes = { "application/JSON ", "application/XML " }) String getConsumes() { return "Consumes attribute "; }}Copy the code

In the code, the getProduces() method produces a JSON response, and the getConsumes() method handles both JSON and XML content in the request.


leoxu

Use @requestMapping to handle headers

The @requestmapping annotation provides a header element to narrow down the RequestMapping based on the header content in the request.

Where you can specify the value of the header element, use the format myHeader = myValue:

@RestController @RequestMapping("/home ") public class IndexController { @RequestMapping(value = "/head ", headers = { "content-type=text/plain " }) String post() { return "Mapping applied along with headers "; }}Copy the code

In the code above, the headers attribute of the @requestMapping annotation Narrows the mapping to the POST () method. With this, the POST () method will only handle requests to /home/head where the Content-Typeheader is specified as text/plain.

You can also specify multiple headers as follows:

@RestController @RequestMapping("/home ") public class IndexController { @RequestMapping(value = "/head ", headers = { "content-type=text/plain ", "content-type=text/html " }) String post() { return "Mapping applied along with headers "; }}Copy the code

This way, the POST () method can accept both text/plain and text/ HTML requests.


leoxu

Use @requestMapping to handle request parameters

The @requestmapping direct params element further helps us narrow down the location of the RequestMapping. With the params element, you can have multiple handlers handle requests to the same URL with different parameters.

You can define parameters in the format myParams = myValue, or you can use wildcards to specify that specific parameter values are not supported in the request.

@RestController
@RequestMapping("/home ")
public class IndexController {
    @RequestMapping(value = "/fetch ", params = {
        "personId=10 "
    })
    String getParams(@RequestParam("personId ") String id) {
        return "Fetched parameter using params attribute =  " + id;
    }
    @RequestMapping(value = "/fetch ", params = {
        "personId=20 "
    })
    String getParamsDifferent(@RequestParam("personId ") String id) {
        return "Fetched parameter using params attribute =  " + id;
    }
}Copy the code

In this code, the getParams() and getParamsDifferent() methods can both handle the same URL (/home/fetch), but which method to execute depends on the configuration of the Params element.

For example, when the URL is /home/fetch? When id=10, getParams() is executed because id is 10. For localhost: 8080 / home/fetch? For the URL personId=20, the getParamsDifferent() method is executed because the id value is 20.


leoxu

Use @requestMapping to handle dynamic URIs

The @requestMapping annotation can be used in conjunction with the @Pathvaraible annotation to handle dynamic URIs, whose values can be used as parameters for processing methods in the controller. You can also use regular expressions to process only dynamic URIs that match the regular expression.

@RestController @RequestMapping("/home ") public class IndexController { @RequestMapping(value = "/fetch/{id} ", method = RequestMethod.GET) String getDynamicUriValue(@PathVariable String id) { System.out.println("ID is " + id); return "Dynamic URI parameter fetched "; } @RequestMapping(value = "/fetch/{id:[a-z]+}/{name} ", method = RequestMethod.GET) String getDynamicUriValueRegex(@PathVariable("name ") String name) { System.out.println("Name is " + name); return "Dynamic URI parameter fetched using regex "; }}Copy the code

In this code, the method getDynamicUriValue () will be launched to localhost: 8080 / home/fetch / 10 request execution. Here the getDynamicUriValue() method id parameter is also dynamically populated with the value 10.

Methods getDynamicUriValueRegex () will be launched to localhost: 8080 / home/fetch/category/tshirt request execution. However, if the request is /home/fetch/10/shirt, an exception will be thrown because the URI does not match the regular expression.

@pathVariable runs differently from @requestParam. You use @pathvariable to get the query parameter value from the URI. In other words, you use @requestParam to get parameter values from the URI template.


leoxu

@requestMapping Specifies the default processing method

In a controller class, you can have a default handler that is executed when there is a request to the default URI.

Here is an example of the default handling method:

@RestController @RequestMapping("/home ") public class IndexController { @RequestMapping() String default () { return "This is a default method for the class "; }}Copy the code

In this code, a request to /home will be handled by default() because the annotation does not specify any value.


leoxu