说说Spring中的 @RestController 和 @Controller
Spring MVC执行流程已是JAVA面试中老生常谈的问题,相信各位小伙伴也是信手拈来。今天我们来谈谈另一个面试中必会必知的问题: @RestController和@Controller的区别?
- Spring MVC中的REST实现
- @Controller + @ResponseBody注解
- @RestController注解
Spring MVC 与 REST
基于注解的MVC框架简化了创建RESTful web服务的过程。传统的Spring MVC控制器和RESTful web服务控制器之间的关键区别是HTTP响应体的创建方式。传统的MVC控制器依赖于视图技术,基于REST的web服务控制器仅返回对象,而对象数据直接以JSON/XML的形式写入HTTP响应。
Spring MVC对 REST 的支持
支持以下方式来创建 REST 资源:
- 控制器可以处理所有的HTTP方法,包含四个主要的REST方法:GET、PUT、DELETE以及POST;
- 消息转换器(Message conversion)将资源的JAVA表述形式转换为发送给客户端的表述形式;
- 借助于 SpringMVC 的一系列注解,构建 REST API;
- 借助 RestTemplate,Spring应用能够方便地使用REST资源;
典型的Spring MVC工作流

在传统的工作流中,ModelAndView对象是从控制器转发到客户机的,通过在方法上加@ResponseBody,Spring直接从控制器返回数据,而不需要查找视图。从4.0版本开始,随着@RestController注释的引入,这个过程得到了进一步简化。下面将解释每种方法。
使用@Controller + @ResponseBody注解
@Controller用于标记在一个类上,使用它标记的类就是一个Spring MVC Controller对象,分发处理器会扫描使用该注解的类的方法,并检测该方法是否使用了@RequestMapping注解。
@ResponseBody注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区,通常用来返回 JSON 或者 XML 数据,返回 JSON 数据的情况比较多。
Spring有一个在后台注册的HttpMessageConverters列表。HTTPMessageConverter的职责是根据预定义的mime类型将请求主体转换为特定的类,然后再转换回响应主体。每当发出的请求点击@ResponseBody时,Spring循环遍历所有已注册的HttpMessageConverters,寻找第一个符合给定mime类型和类的请求,然后将其用于实际的转换。

代码示例
创建实体类:
package com.laocaicai.week1.entity;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Dog")
public class DogEntity {
String name;
String breed;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
public DogEntity() {
}
}
创建Controller:
package com.laocaicai.week1.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.laocaicai.week1.entity.DogEntity;
@Controller
@RequestMapping("dogs")
public class DogController {
DogEntity dog = new DogEntity();
@RequestMapping(value = "/{name}", method = RequestMethod.GET, produces = "application/json")
public @ResponseBody DogEntity getDogInJSON(@PathVariable String name) {
dog.setName(name);
dog.setBreed("中国细犬");
return dog;
}
@RequestMapping(value = "/{name}.xml", method = RequestMethod.GET, produces = "application/xml")
public @ResponseBody DogEntity getDogInXML(@PathVariable String name) {
dog.setName(name);
dog.setBreed("中国细犬");
return dog;
}
}
在Spring配置文件中添加
和标签,前者用于激活注释并扫描包以查找和注册应用程序上下文中的bean,后者增加了对读取和写入JSON/XML的支持(对于返回JSON格式数据,需要导入jackson-databind依赖;对于XML格式,需要导入jaxb-api-osgi依赖)
使用URL:http://localhost:8687/week_1/dogs/哮天犬,输出JSON:

使用URL:http://localhost:8687/week_1/dogs/哮天犬.xml,输出XML:

使用@RestController注解
Spring 4.0引入了@RestController,@RestController注解是一种快捷方式,它所声明的控制器在返回响应时,就如同使用了@ResponseBody 注解一样。它会告诉Spring 将返回类型序列化为合适的格式,默认情况下为JSON 格式。通过用@RestController注释控制器类,您不再需要向所有请求映射方法添加@ResponseBody。
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.stereotype.Controller;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
String value() default "";
}

要在我们的示例中使用@RestController,我们所需要做的就是将@Controller修改为@RestController并从每个方法中删除@ResponseBody。生成的类应该如下所示
package com.laocaicai.week1.controller;
import com.laocaicai.week1.entity.DogEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("2dogs")
public class DogRestController {
DogEntity dog = new DogEntity();
@RequestMapping(value = "/{name}", method = RequestMethod.GET, produces = "application/json")
public DogEntity getDogInJSON(@PathVariable String name) {
dog.setName(name);
dog.setBreed("中国细犬");
return dog;
}
@RequestMapping(value = "/{name}.xml", method = RequestMethod.GET, produces = "application/xml")
public DogEntity getgetDogInXMLInXML(@PathVariable String name) {
dog.setName(name);
dog.setBreed("中国细犬");
return dog;
}
}
注意,我们不再需要将
@ResponseBody添加到请求映射方法中,在进行更改之后,再次在服务器上运行应用程序会产生与之前相同的输出。
总结
通过本篇的介绍,小伙伴们会发现使用@RestController非常简单,是从Spring v4.0开始创建MVC RESTful web服务的首选方法。@RestController(Spring4+)相当于@Controller + @ResponseBody,返回json或者xml格式数据;如果在控制器类上使用@RestController来代替@Controller的话,Spring将会为该控制器的所有处理方法应用消息转换功能,我们不必为每个方法都添加@ResponseBody了。
参考资料:
- 跟开涛学SpringMVC
- SpringMVC中Controller的@ResponseBody注解分析
- 【SpringBoot】 http请求注解之@RestController
- @RestController注解初步理解
- Spring Framework: @RestController vs. @Controller
本文作者:Srivatsan Sundararajan, 翻译:laocaicaicai
原文链接:https://dzone.com/articles/spring-framework-restcontroller-vs-controller
译文首发:http://blog.didispace.com/tr-spring-framework-restcontroller-vs-controller/
本文有spring4all技术翻译组完成,更多国外前沿知识和干货好文,欢迎关注公众号:后端面试那些事儿。
说说Spring中的 @RestController 和 @Controller的更多相关文章
- Spring中@Component注解,@Controller注解详解
在使用Spring的过程中,为了避免大量使用Bean注入的Xml配置文件,我们会采用Spring提供的自动扫描注入的方式,只需要添加几行自动注入的的配置,便可以完成 Service层,Controll ...
- 【spring Boot】Spring中@Controller和@RestController之间的区别
spring Boot入手的第一天,看到例子中的@RestController ............. 相同点:都是用来表示Spring某个类的是否可以接收HTTP请求 不同点:@Controll ...
- Spring中@Controller和@RestController之间的区别
1. Controller, RestController的共同点 都是用来表示Spring某个类的是否可以接收HTTP请求 2. Controller, RestController的不同点 @C ...
- 【spring boot】spring boot中使用@RestController不起作用,不返回json,依旧去找访问接口的请求地址对应的页面
问题描述: spring boot中使用@RestController不起作用,不返回json,依旧去找访问接口的请求地址对应的页面 表现结果: 1>使用postman测试接口,表现为返回是40 ...
- Spring中@Component注解,@Controller注解详解
在使用Spring的过程中,为了避免大量使用Bean注入的Xml配置文件,我们会采用Spring提供的自动扫描注入的方式,只需要添加几行自动注入的的配置,便可以完成 Service层,Controll ...
- SpringBoot 中 @RestController 和 @Controller 的区别
1 - 在springboot中,@RestController 相当于 @Controller + @ResponseBody;2 - 即在Controller类中,若想返回jsp或html页面,则 ...
- spring mvc中的service和controller中读取不到properties值
根据web.xml读取配置文件中的顺序来看 controller层和service层来自于spring mvc.xml中读取,所以必须要在spring mvc.xml中配置读取资源文件夹方式
- spring aop在mvc的controller中加入切面无效
spring aop在mvc的controller中加入切面无效 因为MVC的controller,aop默认使用jdk代理.要使用cglib代理. 在spring-mybatis.xml配置文件中加 ...
- SpringMVC中@RestController和@Controller的区别
在使用SpringMVC时,对于Controller中的注解@RestController和@Controller需要我们区分清楚 @RestController注解相当于@ResponseBody和 ...
随机推荐
- Charles抓包工具操作指南
一.Charles说明 Charles是HTTP代理/ HTTP监视器/反向代理,使开发人员或测试人员可以查看其计算机与Internet之间的所有HTTP和SSL/ HTTPS通信. 这包括请求,响应 ...
- scrapy 基础组件专题(七):scrapy 调度器、调度器中间件、自定义调度器
一.调度器 配置 SCHEDULER = 'scrapy.core.scheduler.Scheduler' #表示scrapy包下core文件夹scheduler文件Scheduler类# 可以通过 ...
- Dynamics CRM Audit Performance Troubleshooting
记一次Dynamics CRM Audit 查询失败的问题. 客户环境现象:由于业务逻辑需要使用RetrieveAuditDetailRequest API查询相关Record的详细更改信息.但查询过 ...
- matlab中的静态变量与全局变量
matlab中的静态变量和全局变量 1.静态变量 在matlab中,和其他语言一样,函数中的变量一把都是局部变量,也就是说,在函数调用完毕后,变量就会被释放.但是有些时候回希望上次改变的变量在下一次调 ...
- P1100 高低位切换
这个题很简单 直接用左移位(<<)和右移位(>>)就可以过了 #include<iostream> #include<cstdio> using nam ...
- 大型Java进阶专题(八)设计模式之适配器模式、装饰者模式和观察者模式
前言 今天开始我们专题的第八课了.本章节将介绍:三个设计模式,适配器模式.装饰者模式和观察者模式.通过学习适配器模式,可以优雅的解决代码功能的兼容问题.另外有重构需求的人群一定需要掌握装饰者模式. ...
- 五分钟快速搭建Serverless免费邮件服务
1. 引言 本文将带你快速基于 Azure Function 和 SendGrid 构建一个免费的Serverless(无服务器)的邮件发送服务,让你感受下Serverless的强大之处. 该服务可以 ...
- React Native 控制一个component的显示隐藏
// 首先在constructor里: this.state = { visible: false } // 然后在点击事件设置: this.setState({ visible: t ...
- goroutine间的同步&协作
Go语言中的同步工具 基础概念 竞态条件(race condition) 一份数据被多个线程共享,可能会产生争用和冲突的情况.这种情况被称为竞态条件,竞态条件会破坏共享数据的一致性,影响一些线程中代码 ...
- 今天完成顺利编译d:\test\Console.java
今天完成顺利编译d:\test\Console.java import javax.swing.*;import java.awt.event.*; public class Console{ pub ...