Wednesday, May 13, 2020

Difference Between @Controller And @RestController Annotations in Spring

In this post we’ll see the difference between @Controller and @RestController annotations in Spring framework.


@Controller annotation in Spring

In a Spring web MVC project generally a view technology like JSP, Freemarker, Thymeleaf is used to render the view. In that case from a Controller method, model is created and a logical view name is returned which is mapped to a view using the configured ViewResolver.

You may also return the object itself from the Controller method, in that case object data is written to the HTTP response body as JSON/XML. For that you need to use the annotation @ResponseBody explicitly which indicates a method return value should be bound to the web response body.

@RestController annotation in Spring

With RESTful web services interchange of data happens mostly as JSON or XML. In case you are writing a Spring REST service you will have to use @ResponseBody annotation along with the @Controller annotation to indicate that the returned object has to be serialized to the response body.

Unlike Spring Web MVC where mostly controller methods return ModelAndView, with Spring REST services it is the object itself which is returned. So Spring framework from version 4 has introduced a convenience annotation @RestController which combines both @Controller and @ResponseBody annotations. In a controller class annotated with @RestController all the @RequestMapping methods assume @ResponseBody semantics by default.

Following two types are same in Spring MVC.

@Controller
@ResponseBody
public class MessageController {
 ..
   ..
}
@RestController
public class MessageController {
 ..
 ..
}

Note that when @ResponseBody annotation is used on a method, return is serialized to the response body through an HttpMessageConverter.

Concrete implementations of the HttpMessageConverter for the main media (mime) types are provided in the Spring framework and are registered by default with the RestTemplate on the client-side and with RequestMethodHandlerAdapter on the server-side. Appropriate implementation of the HttpMessageConverter based on the mime type is chosen for converting the object.

@Controller Vs @RestController in Spring

1- @Controller annotation is used in Spring Web MVC project where model data is rendered using a view.
@RestController is used in RESTful web services where return value (which is mostly an object) is bound to the response body.

2- With classes annotated with @Controller annotation if you want return value to be converted through HttpMessageConverters and written to the response you will have to annotate the class with an extra annotation @ResponseBody or you can annotate individual handler methods with in the controller class with @ResponseBody annotation.
@RestController annotation is the combination of @Controller + @ResponseBody. With @RestController annotation it is the default behavior that the result will be written to the response body.

3- With @Controller annotation you still have that control that you can annotate individual methods with @ResponseBody annotation.
With @RestController annotation all the handler methods of the class write their result to the response body.

@Controller with @ResponseBody Spring MVC example

@Controller
public class MessageController {
 @RequestMapping(value = "/", method = RequestMethod.GET)
 public String showHome(Model model) {
  model.addAttribute(new User());
  model.addAttribute("message", "Spring MVC example");
  return "home";
 }

 @RequestMapping(value = "/getUser/{userId}", method = RequestMethod.GET, produces="application/json")
 @ResponseBody
 public User getUser(@PathVariable("userId") String userId) {  
  return findUserById(userId);
 }

 // Dummy method to find user
 private User findUserById(String userId) {
  System.out.println("User ID " + userId);
  User user = new User();
  user.setUserId(userId);
  user.setFirstName("Leonard");
  user.setLastName("Nimoy");
  return user;
 }
}

As you can see in this controller class first method showHome() is a typical Spring web MVC handler method that returns a logical view name which resolves to home.jsp because of the following configuration.

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/jsp/" />
  <property name="suffix" value=".jsp" />
</bean>

Second method getUser() is annotated with @ResponseBody annotation. Note that using the produces attribute it is also indicated that the media type is JSON.

You will need to add the following Maven dependency for JSON conversion-

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.6</version>
</dependency>

which adds the following jars.

jackson-databind-2.9.6.jar
jackson-annotations-2.9.0.jar
jackson-core-2.9.6.jar

Running it using the URL- http://localhost:8080/springmvc-config/getUser/101 after deployment gives the following result.

@Controller Vs @RestController Spring

@RestController annotation - Spring example

If we have to write the same controller class as a Rest service using @RestController annotation then there is no need to annotate the getUser() method explicitly with the @ResponseBody annotation.

@RestController
public class MessageController { 
 @RequestMapping(value = "/getUser/{userId}", method = RequestMethod.GET, produces="application/json")
 public User getUser(@PathVariable("userId") String userId) {  
  return findUserById(userId);
 }
 
 // Dummy method to find user
 private User findUserById(String userId) {
  System.out.println("User ID " + userId);
  User user = new User();
  user.setUserId(userId);
  user.setFirstName("Leonard");
  user.setLastName("Nimoy");
  return user;
 }
}

That's all for this topic Difference Between @Controller And @RestController Annotations in Spring. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring MVC Redirect Example
  2. Spring Transaction Management JDBC Example Using @Transactional Annotation
  3. Spring Batch Processing With List of Objects in batchUpdate() Method
  4. Select Query Using NamedParameterJDBCTemplate in Spring Framework
  5. Spring Example Program Using JavaConfig And Annotations

You may also like-

  1. Using Spring Profiles to Switch Environment
  2. How to Inject Null And Empty String Values in Spring
  3. Using util-namespace For Wiring Collection in Spring
  4. Injecting Inner Bean in Spring
  5. Difference Between ArrayList And LinkedList in Java
  6. Lambda Expressions in Java
  7. Array in Java
  8. How to Read And Write Parquet File in Hadoop