In this blog post, I will share the Spring annotations used to map HTTP requests to specific handler methods. These annotations include @PostMapping, @GetMapping, @PutMapping, and @DeleteMapping.
While most Spring Boot applications use the @RequestMapping annotation, which I will also cover in this post, I’ll begin with the newer shortcut annotations that have been available since Spring 4.3.
New Spring Boot REST Request Annotations
- @PostMapping – Handle HTTP POST Requests
- @GetMapping – Handle HTTP Get Requests
- @PutMapping – Handle HTTP Put Requests
- @DeleteMapping – Handle HTTP Delete Requests
Here is a simple Rest Controller class that utilizes Spring Boot’s REST request annotations.
@RestController @RequestMapping("users") public class UserController { @Autowired UserService userService; @GetMapping("/status/check") public String status() { return "working"; } @GetMapping("/{id}") public String getUser(@PathVariable String id) { return "HTTP Get was called"; } @PostMapping public String createUser(@RequestBody UserDetailsRequestModel requestUserDetails) { return "HTTP POST was called"; } @DeleteMapping("/{userId}") public String deleteUser(@PathVariable String userId) { return "HTTP DELETE was called"; } @PutMapping("/{userId}") public String updateUser(@PathVariable String userId, @RequestBody UserDetailsRequestModel requestUserDetails) { return "HTTP PUT was called"; } }
Request Annotations and their Attributes
The annotations mentioned above can each accept a list of attributes that help in specifying the binding between an HTTP Request and a Java method.
For instance, you may have two methods that handle HTTP GET requests, but they will be accessible through different URL paths.
Binding a Method to a Specific URL Path
Take a look at the following two methods, annotated with @GetMapping. Each @GetMapping annotation specifies a different URL path. The first method will be triggered when an HTTP GET request is sent to /status/check, while the second one expects a variable value of {id}, such as /17fhyr37 or /4hgj6j94jwg65.
@GetMapping("/status/check") public String status() { return "Working"; } @GetMapping("/{id}") public String getUser(@PathVariable String id) { return "HTTP Get was called"; }
Returning JSON or XML
You can use the produces attribute with the request annotation to specify the content type (JSON, XML) that your Web Service endpoint can return.
@GetMapping(path = "/{id}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}) public UserModel getUser(@PathVariable String id) { // other code here to create UserModel object return userModel; }
If you want your Spring application to return more complex XML structures, you can add the following dependency to your pom.xml file:
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency>
@RequestMapping Annotation
In addition to the annotations mentioned above, you can also use the @RequestMapping annotation, which is commonly used in most Spring Boot REST Web Service projects. With this annotation, you can map any request to a specific method. The following is an example of using the @RequestMapping annotation for each CRUD operation.
HTTP GET Request
A few HTTP GET request mapping examples:
@RequestMapping(method=RequestMethod.GET)
@RequestMapping(method=RequestMethod.GET, path = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
@RequestMapping(method=RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
@RequestMapping(method=RequestMethod.GET, path = "/{id}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
HTTP POST request
To map HTTP Post request to a method, we just need to change the Request Method type:
@RequestMapping(method=RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@RequestMapping(method=RequestMethod.POST, path = "/{id}", consumes=MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
Please note that if you want your Web Service endpoint to be able to return information in either XML or JSON format, depending on the value of the Accept header, you need to use curly braces {} and list the supported media types as follows:
@RequestMapping(method=RequestMethod.POST, path = "/{id}", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
Note: Please note that if you intend to receive MediaType.APPLICATION_XML_VALUE as the response from your Web Service endpoint, you must include the Accept header in your HTTP Request with the value application/xml. For example, you can refer to the curl example given below:
curl -X GET \ http://localhost:8080/users/Ow8EG5GAvkCa9kEHGqLTQpR32zSmhd \ -H 'accept: application/xml' \ -H 'authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0QHRlc3QuY29tIiwiZXhwIjoxNTIzMDMwNTg4fQ.rnOqIEpmh6xQYBPkcRHp9DOnT8M5a7o9De6a7ZE7z2nBKfNpgXNrXgFQnlUi01CnltOP-iXyprsGhB4wvkafcg'
Read Request Body with @RequestBody annotation
Spring Boot provides the @RequestBody
annotation to bind the request body of a HTTP POST, PUT or PATCH request to a method parameter in your controller. This annotation is useful when you need to extract data from the request body, for example when creating or updating a resource.
Here’s an example of how to use the @RequestBody
annotation in your controller method:
@PostMapping("/users") public ResponseEntity<User> createUser(@RequestBody User user) { User savedUser = userRepository.save(user); return ResponseEntity.ok(savedUser); }
In the above example, the createUser
method accepts a User
object in the request body and returns a ResponseEntity
with the saved user object.
By default, Spring Boot uses Jackson to deserialize the request body into a Java object. You can customize the deserialization process using Jackson annotations such as @JsonFormat
and @JsonProperty
.
If the request body is invalid or not present, Spring Boot returns a 400 Bad Request
response by default. You can customize the response using exception handling.
Note that the @RequestBody
annotation can only be used once in a controller method. If you need to bind multiple request parameters, you can use the @ModelAttribute
annotation or create a custom DTO class that contains all the parameters.
In addition to JSON, Spring Boot also supports other media types such as XML and form data. You can specify the media type using the consumes
attribute of the request mapping annotation, for example:
@PostMapping(value = "/users", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) public ResponseEntity<User> createUser(@RequestBody MultiValueMap<String, String> formData) { // ... }
In the above example, the createUser
method accepts form data in the request body and returns a ResponseEntity
with the saved user object.
Overall, the @RequestBody
annotation is a powerful tool for handling HTTP request bodies in your Spring Boot REST endpoints.
Video tutorials
Frequently Asked questions
- How do I handle file uploads in Spring Boot RESTful APIs?
You can use the @RequestParam or @RequestPart annotations to bind files to a controller method parameter and use the MultipartFile interface to handle file uploads. - How do I handle exceptions in Spring Boot RESTful APIs?
You can use the @ExceptionHandler annotation to handle exceptions at a global level or use try-catch blocks in your controller methods to handle exceptions specific to that method. - What is the difference between @PostMapping and @PutMapping annotations?
@PostMapping is used for creating a new resource while @PutMapping is used for updating an existing resource. - How do I handle validation errors in Spring Boot RESTful APIs?
You can use the @Valid and @RequestBody annotations to validate request body parameters and use the @ControllerAdvice annotation to handle validation errors at a global level.