Spring @RequestMapping (with Examples)

Spring @RequestMapping annotation, part of Spring MVC module, is used for mapping HTTP requests to handler methods in the @Controller classes. This annotation allows sufficient flexibility to define custom URL patterns, HTTP methods, request parameters, headers, and more.

Let us understand how to use this annotation effectively in a Spring MVC application.

1. Using @RequestMapping Annotation

We can define the @RequestMapping annotation in two places:

  • Class Level
  • Method level

When applied at the class level, it applies to all handler methods as well. For example, look at the followng EmployeeController code having basic CRUD operations.

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/api/employees/*")
public class EmployeeController {

  @RequestMapping
  public String getModuleInfo(Model model) {
    // return module info
    return "employeesManagementInfo.xsd";
  }

  // Add a new employee
  @RequestMapping(value = "/add", method = RequestMethod.POST)
  public ResponseEntity<Employee> addEmployee(@RequestBody Employee employee) {

    // Save in database
    return new ResponseEntity<>(employee, HttpStatus.CREATED);
  }

  // Get an employee by ID
  @RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
  public ResponseEntity<Employee> getEmployee(@PathVariable Long id) {

    // Get from database
    return new ResponseEntity<>(HttpStatus.NOT_FOUND);
  }

  // Get all employees
  @RequestMapping(value = "/all", method = RequestMethod.GET)
  public ResponseEntity<List<Employee>> getAllEmployees() {

    // Get from database
    return new ResponseEntity<>(employeeList, HttpStatus.OK);
  }

  @RequestMapping(value={"/remove", "/delete"})
  public ResponseEntity removeEmployee(@RequestParam("id") String id) {
    
    //handle 
  }
}

If there are multiple URLs which can be mapped to single method then you can pass an array of string parameters having all different URLs to value attribute e.g. we did this for remove() method in above example. This method will be called if you call URL ‘/remove‘ or ‘/delete‘.

Another thing to note is that first method getModuleInfo() lacks a URL value. Since the class level uses the ‘/api/employees/*’ URL wildcard so this handler method is executed as a catch block if no other matched for any request. So any URL request (e.g., ‘/api/employees/data‘ triggers this method.

2. Stereotype Annotations

Since Spring 4.3, we have use 5 new specialized annotations in place of @RequestMapping annotation. These new annotations are merely composed annotations for clean and easy-to-understand code practices. They do not offer any functionality or performance improvement over @RequestMapping.

AnnotationShorthand for
@GetMapping@RequestMapping(method = RequestMethod.GET)
@PostMapping@RequestMapping(method = RequestMethod.POST)
@PutMapping@RequestMapping(method = RequestMethod.PUT)
@DeleteMapping@RequestMapping(method = RequestMethod.DELETE)
@PatchMapping@RequestMapping(method = RequestMethod.PATCH)

Using these annotations, we can rewrite the EmployeeController APIs as follows:

@RestController
@RequestMapping("/api/employees/*")
public class EmployeeController {

    @GetMapping("/{id}")
    public ResponseEntity<Employee> getEmployee(@PathVariable Long id) {
        // Method implementation
    }

    @PostMapping("/add")
    public ResponseEntity<Employee> addEmployee(@RequestBody Employee employee) {
        // Method implementation
    }
}

3. Mapping URLs

The @RequestMapping annotation allows passing dynamic values in the path (called path parameters) and we can extract them using the @PathVariable annotation.

In the following example, we can pass different values for ‘userId‘ and ‘orderId‘ and they all map to the same handler method. Spring framework extracts both values from the URL and maps them to the respective parameters in the ‘getUserOrder()‘ method.

@Controller
@RequestMapping("/api/users")
public class UserController {

    @RequestMapping("/{userId}/orders/{orderId}")
    public String getUserOrder(@PathVariable("userId") Long userId,
                               @PathVariable("orderId") Long orderId, Model model) {

        // method implementation
    }
}

The @RequestMapping allows using regular expressions in the pattern string, as well. This allows to put a very basic validation check in the input value.

In the following example, Spring will ensure that the ‘year‘ is a 4-digit number and ‘month‘ is a 2-digit number. If values are correct then Spring maps them to the respective parameters. If not, then URL is not matched whci may result into 404 error.

@RequestMapping("/view/{year:\\d{4}}/{month:\\d{2}}")
public String viewArticle(@PathVariable("year") int year,
                          @PathVariable("month") int month, Model model) {

  
  // method implementation
}

4. Mapping Request Parameters and Headers

When using @RequestMapping annotation, we can use the following annotations to handle the request parameters and headers:

AnnotationPurpose
@RequestParamMaps the request parameters or query parameters
@RequestHeaderMaps the request headers

In the following example, we can invoke the URLs /search/results or /search/results?query=spring. Both will work because the query parameter is optional.

In the second method, Spring maps the Client-Id and Client-Secret request headers to the respective parameters in the handler method. These patameters are mandatory. If we do not send these headers then Spring will throw a MissingRequestHeaderException.

@RequestMapping("/search/results")
public String search(@RequestParam(value = "query", required = false, defaultValue = "default") String query) {

  // Logic to perform search based on query
  return "searchResults";
}

@RequestMapping("/info")
public String getDataInfo(@RequestHeader("Client-Id") String clientId,
        @RequestHeader("Client-Secret") String clientSecret, Model model) {

  //Method implementation
}

5. Content Negotiation

The content negotiation is a mechanism for selecting the best representation of a resource based on client and server preferences such as XML or JSON. The @RequestMapping annotation allows to to specify the media types that a method can produce or consume using the attributes ‘produces‘ and ‘consumes‘.

  • The client sends an Accept header in the HTTP request to indicate the media types it can accept.
  • The server uses the Content-Type header to specify the media type of the response it is sending.

In the following example:

  • The getProductAsJson method will be invoked if the client accepts application/json.
  • The getProductAsXml method will be invoked if the client accepts application/xml.
@RequestMapping(value = "/product", produces = "application/json")
public Product getProductAsJson() {
  //return data
}

@RequestMapping(value = "/product", produces = "application/xml")
public Product getProductAsXml() {
  //return data
}

Drop me your comments/questions in comments section.

Happy Learning !!

Comments

Subscribe
Notify of
guest
4 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.