说说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和 ...
随机推荐
- Oracle基础介绍及常用相关sql*plus命令
以管理员身份运行Database Configuration Assistant,新建数据库实例. 要使用Oracle首先要启动Oracle服务,在任务管理器中找到服务,打开有关OracleServi ...
- DVWA学习记录 PartⅥ
Insecure CAPTCHA 1. 题目 Insecure CAPTCHA(全自动区分计算机和人类的图灵测试),意思是不安全的验证码. 指在进行验证的过程中,出现了逻辑漏洞,导致验证码没有发挥其应 ...
- requests接口自动化3-url里带参数的get请求:params
url里带参数的get请求:用params传参 #2.带参数的get请求,把参数写成字典格式,用params传参 para2={"type":"math"} r ...
- java 数据结构(七):Collection接口
1.单列集合框架结构|----Collection接口:单列集合,用来存储一个一个的对象* |----List接口:存储序的.可重复的数据. -->“动态”数组* |----ArrayList. ...
- 数据可视化之powerBI基础(四)深入了解PowerBI的工具提示功能
https://zhuanlan.zhihu.com/p/36804592 在PowerBI上个月的更新中,增加了工具提示功能,这项功能允许您将自己的可视化作品放置到工具提示中,通过鼠标悬停的方式来展 ...
- 数据可视化之DAX篇(八) DAX学习:使用VAR定义变量
https://zhuanlan.zhihu.com/p/64414205 前面介绍如何使用DAX生成日期表的时候,使用了VAR,有人留言问这个VAR怎么理解,那么这篇文章就来介绍VAR以及它的用法. ...
- .NET Core微服务开发服务间调用篇-GRPC
在单体应用中,相互调用都是在一个进程内部调用,也就是说调用发生在本机内部,因此也被叫做本地方法调用:在微服务中,服务之间调用就变得比较复杂,需要跨网络调用,他们之间的调用相对于与本地方法调用,可称为远 ...
- 题解 CF997E 【Good Subsegments】
先将问题进行转化,发现满足\((max-min)-(r-l)=0\)的区间即为好区间. 对于本题这样的统计子区间的问题,先将询问离线,按右端点排序一个一个解决,固定右端点,然后通过数据结构来处理出区间 ...
- 关于docker--详解安装,常规操作,导入导出等(2017-3-29)
测试环境 :CentOS 7.1 64位 目的:展示docker的常规使用(安装,常规操作,导入导出等) 其他:关于原理等请参考文章后面的延伸阅读,本文不做深入探讨,且方法不唯一 0x01 关于安装d ...
- CSS样式基础2
CSS: 一.常用样式:字体,颜色,背景 二.布局:浮动 定位 标签特性 三.标签盒子模型: 边距 边框 四.动画:旋转 渐变 注意:子标签会继承父标签的样式但不是所有的样式都会被继承. 1.1 ...