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. Jmeter系列(43)- 详解 Jmeter 图形化 HTML 压测报告之 Charts 模块

    如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html Charts 介绍 包含了各种详细信息 ...

  2. 【GIT】git详解

    目录 一.基础使用 二.分支管理 三.提交树操作 四.复杂工作流处理 ----------------------------------------------------------------- ...

  3. java 面向对象(十七):单元测试方法

    * Java中的JUnit单元测试 * * 步骤: * 1.中当前工程 - 右键择:build path - add libraries - JUnit 4 - 下一步 * 2.创建Java类,进行单 ...

  4. 数据可视化之powerBI基础(十三)熟练使用Power BI的日期切片器

    https://zhuanlan.zhihu.com/p/64416522 交互式设计可以让用户使用的过程中更具参与感,在PowerBI中经常用到的交互方式就是切片器,利用它可以从不同维度查看数据,切 ...

  5. 数据可视化之powerBI基础(十)快速度量值,帮你更快的进行数据分析

    https://zhuanlan.zhihu.com/p/64414831 刚开始学习PowerBI,最头疼的可能就是度量值了,毕竟用了Excel这么多年,只相信自己眼睛看到的,对于这个"虚 ...

  6. Python函数01/函数的初识/函数的定义/函数调用/函数的返回值/函数的参数

    Python函数01/函数的初识/函数的定义/函数调用/函数的返回值/函数的参数 内容大纲 1.函数的初识 2.函数的定义 3.函数的调用 4.函数的返回值 5.函数的参数 1.函数初识 # def ...

  7. Mysql and ORM

    本节内容 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 创建数据库 外键 增删改查表 权限 事务 索引 python 操作mysql ORM sql ...

  8. InnoDB表存储结构及keyring加密

    ibdata是InnoDB最重要的系统表空间文件,它记录了InnoDB的核心信息,包括事务系统信息.元数据信息,记录InnoDB change buffer的btree,防止数据损坏的double w ...

  9. 如何将你写的脚本程序打包成一个exe可执行程序

    ​    编写的程序打包成一个exe文件,随时可以双击执行,想想是不是很酷.接下来我们一起看一下如何将自己编写的程序打包为一个exe的可执行程序. 将程序打包成exe的好处 除了满足自己的成就感以外, ...

  10. P5836 [USACO19DEC]Milk Visits S 从并查集到LCA(最近公共祖先) Tarjan算法 (初级)

    为什么以它为例,因为这个最水,LCA唯一黄题. 首先做两道并查集的练习(估计已经忘光了).简单来说并查集就是认爸爸找爸爸的算法.先根据线索理认爸爸,然后查询阶段如果发现他们的爸爸相同,那就是联通一家的 ...