@RestController vs @Controller

Both are used to turn any public class into Spring MVC controllers which will be the entry point of any Spring MVC application.

Or we can also say that -> @RestController = @Controller + @ResponseBody;

Let me explain the above equation in detail.

@RestController are used to make PURE REST API Controllers in Spring who’s returned data (JSON or XML) is used by different views (i.e. HTML, JSP etc) to show/parse on the UI. To make any class a rest controller class just annotate them with @RestController along with @RequestMapping annotation(at method level).

i.e.

@RestController
public class HelloController {  
      
   @RequestMapping("/hello")    
   public String getHello() {
       return "Hello There!";    
   }
}

This class says any request with “/hello” in their url will be accepted by getHello() method and “Hello There!” will be returned.

@Controller:

The above code will not work if you just replace @RestController with @Controller. Instead you will get below error.

{
 "timestamp": 1529072828272,
 "status": 500,
 "error": "Internal Server Error",
 "exception": "javax.servlet.ServletException",
 "message": "Circular view path [hello]: would dispatch back to the current handler URL [/hello] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)",
 "path": "/hello"
}

To make that code working if you will have to add @ResponseBody at method level.

i.e.

@Controller
public class HelloController {  
      
   @RequestMapping("/hello") 
   @ResponseBody   
   public String getHello() {
      return "Hello There!";    
   }
}

But Why? Because, if any of your request mapping method, like getHello(), contains @ResponseBody annotation it give an indication that a method return value should be bound to the web response body and if we don’t mention @ResponseBody, then the returned String will be considered as one of the View and ViewResolver will start looking for respective view in the application.

But we don’t need @ResponseBody with @RestController annotation. If I show you the code of @RestController interface, its like below.

@Target(value=TYPE) 
@Retention(value=RUNTIME) 
@Documented 
@Controller 
@ResponseBody 
public @interface RestController

And if you notice RestController interface already has @Controller and @ResponseBody annotation applied.

So always use only @RestController if you are creating RESTful APIS which supposed to return either JSON or XML in their response.

Use @Controller if your controller supposed to return only next page view’s name.

GIT Repository: – https://github.com/tektutorial/spring-boot-initial

 

Hope this clear your doubts!!