关于java:spring @Controller和@RestController注释之间的区别

Difference between spring @Controller and @RestController annotation

弹簧@Controller@RestController注释之间的差异。

@Controller注释能否同时用于web mvc和rest应用程序?如果是,我们如何区分它是Web MVC还是REST应用程序。


  • @Controller用于将类标记为spring mvc控制器。
  • @RestController是一种方便的注释,只需添加@Controller@ResponseBody注释即可(参见:javadoc)。

所以下面两个控制器定义应该做相同的事情

1
2
3
4
5
6
@Controller
@ResponseBody
public class MyController { }

@RestController
public class MyRestController { }


在下面的代码中,我将向您展示不同之处在@Controller之间

1
2
3
4
5
6
7
8
9
10
@Controller
public class restClassName{

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

@RestController

1
2
3
4
5
6
7
8
9
@RestController
public class restClassName{

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

默认情况下激活@ResponseBody。您不需要将它添加到函数签名之上。


@RestController注释类与@Controller相同,但处理程序方法上的@ResponseBody是隐含的。


如果使用@RestController,则无法返回视图(在Spring/Springboot中使用Viewresolver),在这种情况下不需要@ResponseBody

如果使用@Controller,则可以在SpringWebMVC中返回视图。


事实上,要小心-它们不完全一样。

如果您在应用程序中定义了任何拦截器,它们将不适用于注释为@RestController的控制器,但是它们与注释为@Controller的控制器一起工作。

即拦截器配置:

1
2
3
4
5
6
7
8
9
10
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {


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

}

在弹簧控制器的声明中:

1
2
@Controller
public class AdminServiceController {...

不过,会有用的

1
2
@RestController
public class AdminServiceController {...

不会导致拦截器与之关联。


正如在Spring文档(Spring RestController文档)中可以看到的,REST Controller注释与控制器注释相同,但是假定默认情况下@响应体是活动的,所以所有JSON都被解析为Java对象。


Spring4+中新的@restcontroller注释,它将类标记为一个控制器,其中每个方法都返回一个域对象而不是视图。它是@controller和@responsebody的缩写。


从弹簧4.0.1开始提供@RestController。这些控制器表明这里@requestmapping方法默认采用@responsebody语义。

在早期版本中,类似的功能可以通过以下方式实现:

  • @RequestMapping@ResponseBody@RequestMapping(value ="/abc", method = RequestMethod.GET, produces ="application/xml")
    public @ResponseBody MyBean fetch(){
    return new MyBean("hi")
    }
    耦合

  • 可以用作将JSON与Jackson或XML一起使用的方法之一。

  • mybean的定义如下
  • @XmlRootElement(name ="MyBean")
    @XmlType(propOrder = {"field2","field1"})
    public class MyBean{
    field1
    field2 ..
    //getter, setter
    }

  • 在MVC中,@ResponseBody被视为视图,它是直接发送的,而不是从Dispatcher Servlet发送的,各个转换器将响应转换为相关格式,如text/html、application/xml、application/json。
  • 然而,restcontroller已经与responsebody和各自的转换器耦合。其次,在这里,因为它不是转换ResponseBody,而是自动转换为HTTP响应。


    • @Controller:此注释只是@Component的专用版本,它允许基于类路径扫描自动检测控制器类。
    • @RestController:此注释是@Controller的专用版本,它自动添加@Controller@ResponseBody注释,因此我们不必在映射方法中添加@ResponseBody

    与使用@controller和@responsebody不同,@restcontroller让我们在Spring4.0及更高版本中公开RESTAPI。


    @RestController@Controller@ResponseBody的组合,如果方法签名中不使用@ResponseBody,则需要使用@RestController