425

Difference between spring @Controller and @RestController annotation.

Can @Controller annotation be used for both Web MVC and REST applications?
If yes, how can we differentiate if it is Web MVC or REST application.

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Srikanth
  • 4,349
  • 3
  • 13
  • 8
  • 5
    `@RestController` it is designed to follow the `REST architectural design`. As the main purpose of an `REST API` it is to provide only data to be processed by another application. Therefore, as explained below you can only send data cannot return a view. – TOMAS Oct 14 '21 at 14:11

15 Answers15

552
  • @Controller is used to mark classes as Spring MVC Controller.
  • @RestController is a convenience annotation that does nothing more than adding the @Controller and @ResponseBody annotations (see: Javadoc)

So the following two controller definitions should do the same

@Controller
@ResponseBody
public class MyController { }

@RestController
public class MyRestController { }
micha
  • 47,774
  • 16
  • 73
  • 80
  • http://stackoverflow.com/questions/35407390/restcontroller-without-responsebody-on-methods-work-incorrect – gstackoverflow Feb 15 '16 at 10:58
  • 71
    I think @RestController also converts the response to JSON/XML automatically. – arnabkaycee Oct 21 '16 at 13:05
  • 1
    Just sharing a link to a Spring tutorial explaining the difference https://spring.io/guides/gs/rest-service/ – Mina Wissa Dec 25 '16 at 14:49
  • 13
    Also if you use template engine like `Thymeleaf` it will not work with `@RestController` because of `@ResponseBody` which included in this annotation. – Sonique Jun 26 '17 at 07:44
  • 4
    `@ResponseBody` makes the returned objects to something that could be in the body, e.g. JSON or XML ([source](https://stackoverflow.com/a/28647129/562769)) – Martin Thoma Jun 29 '17 at 09:49
  • add @micha's words; There is a good explanation and an example in this link https://www.baeldung.com/spring-controller-vs-restcontroller – fgul Feb 06 '19 at 08:13
  • How does `@Controller` knows that it needs to get a view compared to `@RestController` which wraps responses in ResponseEntity? – piepi Jun 30 '21 at 22:17
  • 1
    @piepi If `@ResponseBody` is not present Spring tries to look up a view. With `@ResponseBody` (which is included with `@RestController`) Spring converts the objects returned by controller methods to the appropriate format based on Accept headers – micha Jul 10 '21 at 20:36
  • `@Controller` - Available since 2.5 version of spring framework `@RestController` - Available since 4.0 version of spring framework – AdityaKapreShrewsburyBoston Aug 17 '21 at 13:59
84

In the code below I'll show you the difference between @controller

@Controller
public class RestClassName{

  @RequestMapping(value={"/uri"})
  @ResponseBody
  public ObjectResponse functionRestName(){
      //...
      return instance;
   }
}

and @RestController

@RestController
public class RestClassName{

  @RequestMapping(value={"/uri"})
  public ObjectResponse functionRestName(){
      //...
      return instance;
   }
}

the @ResponseBody is activated by default. You don't need to add it above the function signature.

s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
BERGUIGA Mohamed Amine
  • 6,094
  • 3
  • 40
  • 38
44

@RestController is the combination of @Controller and @ResponseBody.

Flow of request in a @Controller class without using a @ResponseBody annotation:

enter image description here

@RestController returns an object as response instead of view.

enter image description here

Joby Wilson Mathews
  • 10,528
  • 6
  • 54
  • 53
38

If you use @RestController you cannot return a view (By using Viewresolver in Spring/springboot) and yes @ResponseBody is not needed in this case.

If you use @Controller you can return a view in Spring web MVC.

Ajinkya
  • 22,324
  • 33
  • 110
  • 161
Ravi Wadje
  • 1,145
  • 1
  • 10
  • 15
  • Yes, @ResponseBody can be put on a method and indicates that the return type should be written straight to the HTTP response body (and not placed in a Model, or interpreted as a view name) – PraveenKumar Lalasangi Aug 31 '19 at 13:27
25

@RestController annotated classes are the same as @Controller but the @ResponseBody on the handler methods are implied.

Bart
  • 17,070
  • 5
  • 61
  • 80
16

Actually, be careful - they are not exactly the same.

If you define any interceptors within your application, they will not apply to Controllers annotated as @RestController, however they do work with @Controller annotated controllers.

ie. configuration for the interceptor:

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TemplateMappingInterceptor()).addPathPatterns("/**", "/admin-functions**").excludePathPatterns("/login**");
    }

}

and in the declaration of a Spring controller:

@Controller
public class AdminServiceController {...

Will work, however

@RestController
public class AdminServiceController {...

does not end up having the interceptor being associated with it.

bertybro
  • 600
  • 5
  • 5
  • 2
    `@RestController` was introduced in Spring 4x. This annotation is also annotated itself by `@Controller` so if it not working like an `@Controller` then report this as a bug. – gaoagong Oct 01 '15 at 17:01
  • @bertybro, that's not quite right. You can associate an `Interceptor` to a `@RestController`. – Ravi-A-Doer Feb 05 '17 at 09:52
  • I've certainly successfully attached an `Interceptor` to a `@RestController`. – Ben Barden May 03 '18 at 13:57
  • That would meant, above assumption is false? So certainly it would meant to only assist with implicit @ResponseBody annotation. – Rizwan Shakoor Nov 02 '21 at 09:02
11

As you can see in Spring documentation (Spring RestController Documentation) Rest Controller annotation is the same as Controller annotation, but assuming that @ResponseBody is active by default, so all the Java objects are serialized to JSON representation in the response body.

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
11

@Controller returns View. @RestController returns ResponseBody.

double-beep
  • 5,031
  • 17
  • 33
  • 41
G.Brown
  • 369
  • 3
  • 16
  • 5
    You should explain more. How is this answering the question? – Yunnosch Jul 16 '19 at 08:23
  • @Yunnosch 'view' is your front end like jsp or html. ResponseBody can be xml, json,yaml – G.Brown Jul 16 '19 at 10:42
  • Please [edit] your answer to add helpful information. However I still do not get how it should answer the question. Could you phrase an explanation like "Yes you can/No you cannot, because ...."? – Yunnosch Jul 16 '19 at 19:21
5

THE new @RestController annotation in Spring4+, which marks the class as a controller where every method returns a domain object instead of a view. It’s shorthand for @Controller and @ResponseBody rolled together.

yancy
  • 59
  • 1
  • 2
2

@RestController was provided since Spring 4.0.1. These controllers indicate that here @RequestMapping methods assume @ResponseBody semantics by default.

In earlier versions the similar functionality could be achieved by using below:

  1. @RequestMapping coupled with @ResponseBody like @RequestMapping(value = "/abc", method = RequestMethod.GET, produces ="application/xml") public @ResponseBody MyBean fetch(){ return new MyBean("hi") }

  2. <mvc:annotation-driven/> may be used as one of the ways for using JSON with Jackson or xml.

  3. MyBean can be defined like

@XmlRootElement(name = "MyBean") @XmlType(propOrder = {"field2", "field1"}) public class MyBean{ field1 field2 .. //getter, setter }

  1. @ResponseBody is treated as the view here among MVC and it is dispatched directly instead being dispatched from Dispatcher Servlet and the respective converters convert the response in the related format like text/html, application/xml, application/json .

However, the Restcontroller is already coupled with ResponseBody and the respective converters. Secondly, here, since instead of converting the responsebody, it is automatically converted to http response.

hi.nitish
  • 2,732
  • 2
  • 14
  • 21
2

@Controller is used in legacy systems which use JSPs. it can return views. @RestController is to mark the controller is providing REST services with JSON response type. so it wraps @Controller and @ResponseBody annotations together.

Andrzej Sydor
  • 1,373
  • 4
  • 13
  • 28
Tharindu Eranga
  • 137
  • 3
  • 12
0
  • @Controller: This annotation is just a specialized version of @Component and it allows the controller classes to be auto-detected based on classpath scanning.
  • @RestController: This annotation is a specialized version of @Controller which adds @Controller and @ResponseBody annotation automatically so we do not have to add @ResponseBody to our mapping methods.
Jayendran
  • 9,638
  • 8
  • 60
  • 103
0

The @Controller annotation indicates that the class is a "Controller" like a web controller while @RestController annotation indicates that the class is a controller where @RequestMapping methods assume @ResponseBody semantics by default i.e. servicing REST API

KiranKumar
  • 11
  • 3
-3

@RestController is composition of @Controller and @ResponseBody, if we are not using the @ResponseBody in Method signature then we need to use the @Restcontroller.

Javasick
  • 2,753
  • 1
  • 23
  • 35
sambhu
  • 111
  • 1
  • 5
-3

Instead of using @Controller and @ResponseBody, @RestController let's you expose Rest APIs in Spring 4.0 and above.

  • You want to say *I think @RestController also converts the response to JSON/XML automatically.* ? you used an abstract sentence instead of explain it clearly, I won't suggest that. – cinqS Mar 09 '17 at 03:07
  • Come to think of it, @Controller does the same as it take hte produces and consumes mime types JSON/XML or otherwise...@ResponseBody tells Controller to behave like REST endpoint without producing a View. RestController implicitly does that. – CoffeeBeanie Mar 13 '17 at 06:00