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. Scala 基础(八):Scala 程序流程控制

    1.顺序控制 顺序控制介绍 程序从上到下逐行地执行,中间没有任何判断和跳转. 顺序控制举例和注意事项 Scala中定义变量时采用合法的前向引用.如: def main(args : Array[Str ...

  2. mongodb(一):数据库安装,部署(windows)

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10885038.html,多谢~=.= 安装MongoDB 双击运行msi文件,一直“Next”. ...

  3. keras 文本序列的相关api

    1.word_tokenizer = Tokenizer(MAX_WORD_NUMS)    MAX_WORD_NUMS设置词典的最大值,为一个int型数值 2.word_tokenizer.fit_ ...

  4. Python 实现邮件发送功能(初级)

    在我们日常项目中,会经常使用到邮件的发送功能,如何利用Python发送邮件也是一项必备的技能.本文主要讲述利用Python来发送邮件的一些基本操作. 本章主要包含知识点: 邮件发送原理简述即常用smt ...

  5. 【week1错题集】

    day9[2.f] # day9 题2.f ''' 有如下文件,t1.txt,里面的内容为: 葫芦娃,葫芦娃, 一根藤上七个瓜 风吹雨打,都不怕, 啦啦啦啦. 以r模式打开文件,从‘风吹雨打..... ...

  6. javascript实战 : 简单的颜色渐变

    HTML <div id="color"></div> CSS .item{ display:inline-block; margin:10px; widt ...

  7. 一个通用的两级Makefile例子

    目的 进行如项目的顶层目录后,运行make,即可直接编译项目中所有的源文件,并生成最终的可执行文件 实现头文件自动依赖 添加源文件不用修改Makefile,且可以自动编译新文件 顶层目录下添加文件夹, ...

  8. 一起学Blazor WebAssembly 开发(1)

    最近blazor的WebAssembly 正式版出来了,正好手头有一个项目采用的前后端分离模式做的,后端用的abp vnext(.net core 的一个很著名的框架)框架开发的,其实前端之前考虑的使 ...

  9. DVWA SQL 注入关卡初探

    1. 判断回显 给id参数赋不同的值,发现有不同的返回信息 2. 判断参数类型 在参数后加 ' ,查看报错信息 数字型参数左右无引号,字符型参数左右有引号 4. 引号闭合与布尔类型判断 由于是字符型参 ...

  10. Java进阶专题(十一) 想理解JVM看了这篇文章,就知道了!(中)

    前言 ​ 上次讲解了JVM内存相关知识,今天继续JVM专题. JVM垃圾回收算法 什么是垃圾回收 ​ 程序的运行必然需要申请内存资源,无效的对象资源如果不及时处理就会一直占有内存资源,最终将导致内存溢 ...