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了。

参考资料

本文作者: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的更多相关文章

  1. Spring中@Component注解,@Controller注解详解

    在使用Spring的过程中,为了避免大量使用Bean注入的Xml配置文件,我们会采用Spring提供的自动扫描注入的方式,只需要添加几行自动注入的的配置,便可以完成 Service层,Controll ...

  2. 【spring Boot】Spring中@Controller和@RestController之间的区别

    spring Boot入手的第一天,看到例子中的@RestController ............. 相同点:都是用来表示Spring某个类的是否可以接收HTTP请求 不同点:@Controll ...

  3. Spring中@Controller和@RestController之间的区别

    1. Controller, RestController的共同点 都是用来表示Spring某个类的是否可以接收HTTP请求 2.  Controller, RestController的不同点 @C ...

  4. 【spring boot】spring boot中使用@RestController不起作用,不返回json,依旧去找访问接口的请求地址对应的页面

    问题描述: spring boot中使用@RestController不起作用,不返回json,依旧去找访问接口的请求地址对应的页面 表现结果: 1>使用postman测试接口,表现为返回是40 ...

  5. Spring中@Component注解,@Controller注解详解

    在使用Spring的过程中,为了避免大量使用Bean注入的Xml配置文件,我们会采用Spring提供的自动扫描注入的方式,只需要添加几行自动注入的的配置,便可以完成 Service层,Controll ...

  6. SpringBoot 中 @RestController 和 @Controller 的区别

    1 - 在springboot中,@RestController 相当于 @Controller + @ResponseBody;2 - 即在Controller类中,若想返回jsp或html页面,则 ...

  7. spring mvc中的service和controller中读取不到properties值

    根据web.xml读取配置文件中的顺序来看 controller层和service层来自于spring mvc.xml中读取,所以必须要在spring mvc.xml中配置读取资源文件夹方式

  8. spring aop在mvc的controller中加入切面无效

    spring aop在mvc的controller中加入切面无效 因为MVC的controller,aop默认使用jdk代理.要使用cglib代理. 在spring-mybatis.xml配置文件中加 ...

  9. SpringMVC中@RestController和@Controller的区别

    在使用SpringMVC时,对于Controller中的注解@RestController和@Controller需要我们区分清楚 @RestController注解相当于@ResponseBody和 ...

随机推荐

  1. redis(十七):Redis 安装,部署(WINDOWS环境下)

    1.下载Redis安装文件, 我选择的是 3.0.504 版本,有zip或msi可供下载.   2.解压缩后,打开安装目录 双击redis-server.exe启动redis服务器,双击redis-c ...

  2. Odoo13之在tree视图左上角添加自定义按钮

    前言 首先展示效果图,如下图所示,在资产设备模块tree视图的左上角添加了一个同步资产的按钮. 要完成按钮的添加,分为四步,分别是: 1.编写xml文件,找到相关模型tree视图,并给模型tree视图 ...

  3. 机器学习实战---决策树CART回归树实现

    机器学习实战---决策树CART简介及分类树实现 一:对比分类树 CART回归树和CART分类树的建立算法大部分是类似的,所以这里我们只讨论CART回归树和CART分类树的建立算法不同的地方.首先,我 ...

  4. MySQL事物原理及事务隔离级别

    mysql事物 事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据库的存取.事务的正确执行使得数据库从一种状态转换为另一种状态. 事务必须服从ISO/IEC所制定的ACID原则.AC ...

  5. J.U.C体系进阶(二):juc-locks 锁框架

    Java - J.U.C体系进阶 作者:Kerwin 邮箱:806857264@qq.com 说到做到,就是我的忍道! juc-locks 锁框架 接口说明 Lock接口 类型 名称 void loc ...

  6. T3 成绩单 题解

    这个题本来不归我讲,但我A完之后觉得太坑了,还是讲一下吧. 首先这个题有个重要的地方:(字典顺序,学号全为小写字母,从小到大排列) 字典序和字典顺序是不一样的!!! 我以为是字典序……,wa了,字典顺 ...

  7. ant design pro : 依赖项 webpack-theme-color-replacer 最新版导致项目无法启动?

    重新装了一个项目的依赖,结果发现打不开了? 报错如下: This dependency was not found: * webpack-theme-color-replacer/client in ...

  8. C++语法小记---string和int的相互转换

    string和int的相互转换 string转int istringstream is(""); //构造输入字符串流,流的内容初始化为“12”的字符串 int i; is > ...

  9. 微软如何绑定二次验证码_虚拟MFA_两步验证_身份验证?

    1.登陆Microsoft账户,找到二次验证绑定界面 进入Microsoft,点右上角用户头像进行登陆.之后点“安全性”. 之后点击[更多安全选项] 找到“身份验证应用”(注意不是“双重验证”).点击 ...

  10. Java基础之NIO

    NIO简介: Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API.NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同 ...