Spring @GetMapping and @PostMapping

Learn to create Spring WebMVC REST controllers with @Controller annotation and map HTTP requests with annotations like @RequestMapping, @GetMapping and @PostMapping.

1. Request Mapping Annotations

Spring 4.3 introduced 5 new and more specific annotations for each HTTP request type.

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping
@GetMapping(value = "/users")
public Users getUsers() { ... }

@GetMapping(value = "/users/{id}")
public User getUser(@PathVariable("id") String id) { ... }

@PostMapping(value = "/users")
public User createUser(User user) { ... }

Before Spring 4.3, Spring had only @RequestMapping annotation for mapping all the incoming HTTP request URLs to the corresponding controller methods.

For example, in the given below code, @RequestMapping annotation has been used to map the same HTTP requests. Notice that we have specified the HTTP request type (GET, POST) as the annotation attribute method.

@RequestMapping(value = "/users", method = RequestMethod.GET)
public Users getUsers() { ... }

@RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
public User getUser(@PathVariable("id") String id) { ... }

@RequestMapping(value = "/users", method = RequestMethod.POST)
public User createUser(User user) { ... }

2. Spring @GetMapping Example

  • The @GetMapping annotation is a composed version of @RequestMapping annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.GET).
  • The @GetMapping annotated methods handle the HTTP GET requests matched with the given URI expression.

Let us understand how to write controller methods mapped with @GetMapping annotations. In the following example, we are mapping two GET requests:

  • HTTP GET /users – returns all the users in the system.
  • HTTP GET /users/{id} – returns a user by specified id.
@RestController
public class UserController {
 
    @Autowired
    UserService userService;
 
    @GetMapping("users")
    public ResponseEntity<List<User>> getAll() {

        return new ResponseEntity<>(userService.getAll(), HttpStatus.OK);
    }
 
    @GetMapping("users/{id}")
    public ResponseEntity<User> getById(@PathVariable long id) {

        Optional<User> user = userService.getById(id);
        if (user.isPresent()) {
            return new ResponseEntity<>(user.get(), HttpStatus.OK);
        } else {
            throw new RecordNotFoundException();
        }
    }
}

3. Spring @PostMapping Example

  • The @PostMapping is a specialized version of @RequestMapping annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.POST).
  • The @PostMapping annotated methods handle the HTTP POST requests matched with the given URI expression.
  • As a best practice, always specify the media types (XML, JSON etc.) using the ‘consumes’ and ‘produces’ attributes.

Let us understand how to write controller methods mapped with @PostMapping annotations. In the following example, we are mapping a POST request:

  • HTTP POST /users – creates a new user in the system.
@PostMapping(path = "users", 
        consumes = MediaType.APPLICATION_JSON_VALUE, 
        produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<User> create(@RequestBody User newUser) {

    User user = userService.save(newUser);
    if (user == null) {
        throw new ServerException();
    } else {
        return new ResponseEntity<>(user, HttpStatus.CREATED);
    }
}

4. Annotation Attributes

All request mapping annotations support the following attributes, but they should be used when appropriate for the request type:

  • path or value: specifies the mapping URI. A handler method that is not mapped to any path explicitly is effectively mapped to an empty path.
@PostMapping(value = "/members")

//or

@PostMapping("/members")
  • consumes: consists of one or more media types, one of which must match the request Content-Type header.
@PostMapping("/members", consumes = {"text/plain", "application/*"})
  • produces: consists of one or more media types one of which must be chosen via content negotiation against the “acceptable” media types, generally extracted from the "Accept" header but may be derived from query parameters.
@PostMapping("/members", produces = {"text/plain", "application/*"})
  • headers: specifies the headers of the mapped request, narrowing the primary mapping, with a request only mapped if each such header is found to have the given value.
@PostMapping(value = "/members", headers = "content-type=text/json")  
  • name: Assign a name to the mapping.
@PostMapping(value = "/members", name = "AddNewMember")  
  • params: specifies the parameters of the mapped request, narrowing the primary mapping, with a request only mapped if each such parameter is found to have the given value.
@PostMapping(value = "/members", params = "x-country=USA")  

5. Class-level Shared Attributes

The mapping annotations such as @RequestMapping, @GetMapping and @PostMapping, inherit the annotation attribute values from the @RequestMapping annotation applied at the @RestController class.

In HomeController, the @RequestMapping annotation at the top specifies the produces attribute to MediaType.APPLICATION_JSON_VALUE , so all the handler methods in this class, by default, will return the JSON response.

@RestController
@RequestMapping(path = "/", produces = MediaType.APPLICATION_JSON_VALUE)
public class HomeController
{
	@PostMapping(path = "/members")
	public void addMember(@RequestBody Member member) {
		//code
	}
}

Note that the method-level mapping annotation may override the attribute values by providing its own values. In the following example, the /members API overrides the produces attribute so it will return the XML response to the clients.

@RestController
@RequestMapping(path = "/", produces = MediaType.APPLICATION_JSON_VALUE)
public class HomeController
{
	@PostMapping(path = "/members", produces = MediaType.APPLICATION_XML_VALUE)
	public void addMember(@RequestBody Member member) {
		//code
	}
}

6. Difference between @PostMapping and @RequestMapping

As noted above @PostMapping annotation is one specialized version of @RequestMapping annotation that handles only the HTTP POST requests.

@PostMapping = @RequestMapping(method = { RequestMethod.POST })

Let’s see the difference between @PostMapping and @RequestMapping annotations with a very simple example. Both versions in the given example will work exactly the same. They just have a slightly different syntax.

@RequestMapping(value = "/employees", method = RequestMethod.POST) 
 
@PostMapping("/employees")      //Similar to above declaration

In other words, @PostMapping acts as a shortcut for @RequestMapping(method = RequestMethod.POST). We can see the source code of the @PostMapping annotation which internally uses the @RequestMapping annotation.

@Target({ java.lang.annotation.ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = { RequestMethod.POST })
public @interface PostMapping 
{
    //code
}

7. Summary

Spring MVC has made writing request handlers / REST controller classes and methods very easy. Just add a few annotations like @GetMapping and @PostMapping and put the class where component scanning can find them and configure them in the web application context.

It is also very easy to create attributes at the class level so that all handler methods inherit them by default and can override them when needed.

Same way, you can use other request mapping annotations e.g. @PutMapping, @DeleteMapping and @PatchMapping.

Happy Learning !!

Sourcecode on Github

Leave a Reply

2 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.

Our Blogs

REST API Tutorial