Mapping a URL request in Spring Boot : @RequestMapping

Subscribe to my newsletter and never miss my upcoming articles

@RestController

To start let’s make a Controller , Spring gives a specific controller i.e. @RestController to ensure that all methods within it , returns a REST enabled response. It automatically marshalls and unmarshal incoming JSON/XML request to Java object and sends response of Java objects as JSON/XML output.

We will create a class UserController under package com.codingsaint.userservice.controller and annotate it with @RestController.

package com.codingsaint.userservice.controller;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
}

Here RestController is denotes that this class has to act as a Controller and server incoming requests. The method within it , will be mapped with @RequestMapping to map the requests.

@RequestMapping

@RequestMapping is used for mapping incoming requests to specific method. Obviously for each request , we should have a dedicated unique method. In web application , a request is made of URL path , HTTP verbs like GET , PUT ,POST ,DELETE etc and headers . Each URL with combination of these verb and headers(if added) is unique and for each unique request we must have a unique method handling it.

For example , let’s consider a URL as “/v1/user/{id}” . Here v1 is our api version , and id is the unique it of the user, If we use GET HTTP verb along with the URL to hit the server , it should be considered as request for getting user information with the provided id. At the same time if we use DELETE , it should be considered as deleting the details of user with same id. In both cases we should have a dedicated method annotated with @RequestMapping the handling incoming request.

@RequestMapping can be used at class level as well as on method level. Once used on class level , it is appended to all the method level request mappings. For example , in above method created UserController class we are supposed to map requests for user where version of our API will be v1 , so if we map v1 at class level , we don’t have to map it at all methods inside the class used for mapping URLs.

Let is create a mapping for getting all users but before that we need a user object. We will create a simple POJO class with id , first name, last name and email. We will create User.java inside com.codingsaint.userservice.models , where models denoting package for our model classes.

package com.codingsaint.userservice.models;
public class User{
private Long id;
private String firstName;
private String lastName;
private String email;
//Getters and setters : Do add them
}

In above class we have removed getters and setters for readability , please add them.

Now we will add @RequestMapping at class and methods levels to handle incoming request.


@RestController
@RequestMapping("v1")
public class UserController {
private List users = new ArrayList();
@RequestMapping(value = "users", method = RequestMethod.GET)
protected List getUsers() {
User user = new User();
user.setId(1L);
user.setEmail("");
user.setFirstName("Ray");
user.setLastName("McFallen");
users.add(user);
return users;
}
}

Here we don’t have a database yet, so we have taken a List and initialize it with a dummy user. Now after running UserServiceApplication.java (as a java program/ as spring boot app),with POSTMAN ,ARC (chrome plugins) or with a CURL request , we can see a valid response. Currently if we run it , the application will be up at http://localhost:8080/ and with URL request mapped at http://localhost:8080/v1/users , we get following result.

[
{
“id”: 1,
“firstName”: “Ray”,
“lastName”: “McFallen”,
“email”: “
}
]

Following is a screenshot from POSTMAN

RequestMapping annotation by default works as explained but it can be used with more parameters like consumes, produces, path, name ,headers and params ,path and value are alias of each other. We can have two different methods handing same signature based on URL ,HTTP Verb but different acceptance header.

Let’s add another method as below


@RequestMapping(value = "users", method = RequestMethod.GET ,
headers = "app-id=my-awesome-app")
protected List getUsersWithAppIdHeader() {
return new ArrayList();
}

With addition of this method we can send one request as above and one with header value , app-id=my-awesome-app and both will be resolved separately. Below is the screenshot of same , sending empty list as response.

It is also interesting to note that value, header, consumes ,accepts all accept array , so we can send multiple values to it , which means we can map multiple URL signature to one method but not exactly same URL signature to multiple method which will confuse application to hit which method in case of incoming request.

No Comments Yet