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.
@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
You may also like-