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.
@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 { }
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.
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.
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.
@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:
@RequestMapping
coupled with @ResponseBody
like @RequestMapping(value = "/abc", method = RequestMethod.GET, produces ="application/xml")
public @ResponseBody MyBean fetch(){
return new MyBean("hi")
}
<mvc:annotation-driven/>
may be used as one of the ways for using JSON with Jackson or xml.
@XmlRootElement(name = "MyBean")
@XmlType(propOrder = {"field2", "field1"})
public class MyBean{
field1
field2 ..
//getter, setter
}
@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.
@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.