Open In App

Top 10 Spring MVC Annotations with Examples

Last Updated : 23 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In the world of Spring MVC, annotations are like a reliable assistant for your web applications. They usually work behind the scenes of your application and make tasks easier. Also, they help the developers to communicate clearly with their applications and ensure what the developers actually want to do with their applications.

Spring MVC Annotations with Examples

In this article, we will have a closer look at the Top 10 Spring MVC annotations, each one having its own role. Once you’re familiar with them, you’ll be able to use Spring MVC more confidently and you can create web applications that are both efficient as well as user-friendly.

What are Spring MVC Annotations?

Imagine you’re building a website or web application and you want to make sure that it works smoothly and does what you want it to do. Spring MVC is like a set of tools that helps you build these web applications using Java Programming Language. Now, think of annotations as special notes or instructions that you attach to your code. These notes tell Spring MVC how different parts of your code should work together. They’re like little tags that help Spring MVC understand your code better and make it easier for you to build your web applications.

For more details about Spring Annotations, Follow Spring Annotations.

Top 10 Spring MVC Annotations

Now that we have understood the basics of Spring MVC annotations, let’s learn about the Top 10 Spring MVC annotations with code examples. Here we will be learning about every annotation in detail with examples of source code.

1. @RequestMapping

The @RequestMapping annotation is a class-level annotation. It is used to map HTTP requests to their respective methods. The request mapping annotation is a generic one. This means that it can be used regardless of the request being GET, POST, PUT, DELETE, or PATCH. You can think of the request mapping as an index page. You visit the index page of your book, look up the topic you want to read, and then jump to the particular page number that contains this topic. Similarly, the requests come to this annotation, look up where the method they want to go is, and jump to that method without getting lost. Let us understand the request mapping annotation with a small example.

Java




@RequestMapping(value="/api/v1/geeks")
class RequestMappingDemo {
  @GetMapping("/getMessage")
  public String getMessage() {
    return "GeeksForGeeks";
  }
  @GetMapping("/getGreeting")
  public String sayHello() {
    return "Hello";
  }
}


Class Level Annotation: Annotations that can be applied only to classes.

Method Level Annotations: Annotations that can be applied to methods only.

What is happening in the code above? When the user visits “…/api/v1/geeks/getMessage”, then the request stops at the request mapping annotation. It then looks for the method that should be executed for Uri “/getMessage”. Upon successfully identifying the request, the getMessage method returns “GeeksForGeeks” to the user on the browser page.

2. @Controller

The @Controller annotation is a specialized form of @Component annotation. It is a class level annotation. It simply allows for classes marked as @Configuration to be auto detected by the spring application context. Without the @Controller annotation, you would get an error claiming that no beans were found for the respective class. Let us understand the controller annotation with an example.

Java




//client-class that demands the use of inbuilt RestTemplate class
@RequestMapping(value="/**")
@Controller
public class ControllerDemo {
  @Autowired
  private RestTemplate restTemplate;
  //...your methods here
}
  
//server-class that is providing the restTemplate
@Configuration
public class ProjectConfig {
  @Bean
  public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder.build();
  }
}


What is happening in the code above? In the above code, the client class wants to use an object called RestTemplate. Since, the spring framework has already defined an implementation for this object, we want to be able to use the same in our code. In order to do so, we need to tell the spring framework that “I want to use this class, please generate it’s object at runtime” and to do this we use the @Controller annotation in our client class.

Meanwhile, in the server class, we tell the spring framework that “I will be writing certain methods in this class, that define the objects that I need in my code at runtime”. To achieve this, we use @Configuration annotation. And, we apply the @Bean annotation at the level of the methods to return these particular objects. Thus, a proper “handshake” between @Configuration for server class and @Controller for client class, helps us to achieve the OOP principle of “abstraction” in our code.

3. @ResponseBody

The @ResponseBody annotation can be applied to classes as well as methods. This annotation has to do with what is being sent back to the user as an output. It is used for automatic serialization of the output by a method in the controller layer. Consider the Java Code below that makes use of this annotation:

Java




@ResponseBody
@RequestMapping(value="/gfg")
public class ResponseBodyDemo {
  @GetMapping("/geek1")
  public String method1() {
    return "I am Geek.";
  }
  @GetMapping("/geek1/number")
  public int method2() {
    return 1;
  }
}


Now, the application is started and the user hits the respective URIs “…/gfg/geek1” and “…/gfg/geek1/number”.

The method returns the string and the integer in the respective cases. But because we have used the ResponseBody annotation, before returning to the user, this automatically is converted to a JSON.

Javascript




{
    "output": "I am Geek."
}
  
{
    "output": 1
}


Thus the output of the Response body annotation will be some serializable format like JSON or XML.

4. @RestController

This annotation is simply the combination of @Controller and @ResponseBody annotation. With the @RestController annotation, you no longer need to annotate each and every method with @ResponseBody. Mind you, do not use this annotation when you are rendering pages for example: in thymeleaf. You don’t want to serialize your html code! Let us Understand how this works with code examples from the previous section:

Java




//client-class that demands the use of inbuilt RestTemplate class
@RequestMapping(value="/**")
@RestController
public class ControllerDemo {
  @Autowired
  private MyClass myClass;
  @GetMapping("/geek1")
  public String method1() {
    return "I am Geek.";
  }
  @GetMapping("/geek1/number")
  public int method2() {
    return 1;
  }
}
  
//server-class that is providing the restTemplate
@Configuration
public class ProjectConfig {
  @Bean
  public MyClass method(...) {
    return MyClass.object;
  }
}


5. @RequestParam

The @RequestParam annotation can be used to assign variables to query parameters in Http Requests. Suppose that we want to access a URL with one or more query parameters in it. The URL we visit is: http://localhost:8080/api/v1/geeks?firstname=John&lastname=doe

Now, we want to extract firstname and lastname from this URL. This is where the @RequestParam URL comes in. Let us understand with a code sample:

Java




@RequestMapping(value="/api/v1")
@RestController
public class RequestParamDemo {
  @GetMapping("/geeks")
  public void demo(@RequestParam("firstname") String fname, @RequestParam("lastname") String lname) {
    System.out.println(fname+" "+lname);
  }
}
//Output= John Doe


If we have only one query parameter then mentioning the name of the parameter is totally optional. For eg: If we were passing just the firstname then we could have written: public void demo(@RequestParam String fname).

6. @PathVariable

To understand @PathVariable, let us first look at what are template variables in a URI. Suppose we have an http request as: http://localhost:8080/index/page1 when the user want to view page1. Similarly there are n other pages that can be viewed. The URL for these pages is similar to that of page1 …/index/page2 to ../index/pageN. Now, to generalize what page we want to load based on user’s choice, we can use template variables. Using template variables, we can write the URL as http://localhost:8080/index/{page} where page is variables that has values as page=page1, page2, page3…pageN. Thus {page} here is referred to as a template variable.

At the backend, we can extract these variables from the URL and use them to serve the respective pages. This is where the @PathVariables annotation comes in. It helps us to extract template variables from http URLs and assign them to variables in our code. Let us understand this with the help of a code.

Java




@RestController
@RequestMapping(value="/index")
public class PathVariableDemo {
  @GetMapping("/{page}
  public String getPage(@PathVariable String pageNumber) {
    return "You visited "+pageNumber;
  }
}


Now, if the mapping is /index/page1 User would see the message You visited page1 on their browser window. Similarly for any other pages.

7. @RequestBody

Just like @RequestParam extracts query parameters and the @RequestBody extracts template variables from http URL requests, the @RequestBody annotation helps us to read the data in the body of the http request and allows it’s process by binding it to variables, Maps or POJOs.

Generally, when we know what kind of data is returned from the http body, we can use variables and POJOs. But, incase we have a doubt as to what is being returned with the body, we can use Maps.

Let us see how this works with a code example.

Java




@GetMapping("/userData")
public String getUserAndId(@RequestBody Map<String,String> userData) {
  return "The name of the user is= "+userData.get("name")+" and their id is= "+userData.get("id"); 
}


Now suppose we send the following JSON as request body with our Http Request.

Javascript




{
    "name" : "Geek",
    "dob" : "29-2-99",
    "id" : 3,
    "state: "Uttarakhand"
}


We could have written any number of key-value pairs in request body, and it would mapped to a Map with the respective key-value pairs. In this we simply get the output message as: The name of the user is= Geek and their id is= 3. This is how the @RequestBody annotation works. For more details, read here.

8. @CookieValue

The @CookieValue annotation is used to tie the value of http cookies to the method arguments of controllers in Spring MVC. For eg:

Java




@RestController
@RequestMapping
public class Demo {
  @GetMapping("/user")
  public void getCookieValue(@CookieValue("JSESSIONID") String jSessionId) {
    System.out.println("The session id is: "+jSessionId);
  }
}


On running the above snippet, we can view the JSESSIONID of the current user on the console.

9. @CrossOrigin

The @CrossOrigin is very imported in Spring. If you have a spring backend and a a JavaScript frontend in react, angular or vue and on trying to communicate with the backend you receive a CORS error, then it is likely that you have not used the @CrossOrigin annotation. This annotation is extremely important because it defines what all ports on your computer can communicate with the backend. CORS stands for Cross Origin Resource Sharing. This annotation can be used on the method level or the class level.

Java




@CrossOrigin("http://localhost:3000")
@GetMapping
public String getMessage() {
  return "Hello World";
}


In the above controller method getMessage, we explicitly allow the traffic from localhost:3000(for react frontends) to enter our backend server.

10. @ExceptionHandler

This annotation is used to handle the exceptions in controller classes. Should any exceptions occur, the @ExceptionHandler annotation is used to catch these exceptions and display messages to the users accordingly. The @ExceptionHandler is also called as a Local Exception Handler in spring, because it handles exceptions at the class level.

Java




@Controller
public class MyClass {
  //...controllers
    
  //...Exception Handlers
  @ExceptionHandler(NullPointerException.class)
  public String getErrorMessage1(NullPointerException ex) {
    return "Exception is:" + ex.getMessage();
  }
  @ExceptionHandler(ArrayIndexOutOfBoundsException.class)
  public String getErrorMessage2(ArrayIndexOutOfBoundsException ex) {
    return "Exception is:" + ex.getMessage();
  }
}


In the above code example, if on executing any of the controller methods we get the ArrayIndexOutOfBoundsException then the getErrorMessage2() method is executed. For the NullPointerException, the first method is executed. We can add as many @ExceptionHandlers as we want. They help us to convey to the client why the system is running into errors.

Conclusion

In this article, we have learned about the top 10 Spring MVC annotations and their uses for creating robust web applications. When you know these annotations inside out, you can keep your code neat, handle requests smoothly, and make error messages friendlier for users. Understanding these annotations really well is a key part of becoming great at Spring MVC. ​



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads