@controller注解_Spring 注解 @RestController 和 @Controller 面试必会必知

点击上方蓝色“后端面试那些事儿”,选择“设为星标”

学最好的别人,做最好的我们

0b1a840547e39cdca9c6cc9c7c10d8a6.png

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工作流

00372c48bd5a5b10f8c285077bd4d0c7.png
典型的Spring MVC工作流程.png

在传统的工作流中,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类型和类的请求,然后将其用于实际的转换。

6eb891e5f93f70d460becc89c6460265.png
Spring3.x MVC RESTful网络服务工作流程.png

代码示例

创建实体类:

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:

2e94822d62de38cf5714eefd825f19c6.png
返回JSON格式数据.png

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

564875dcab49699370b724bd7b526d8c.png
返回XML格式数据.png

使用@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 "";
}
ac5614b070a9d1b8c1fb08cb21570bda.png
Spring4.x MVC RESTful网络服务工作流程.png

要在我们的示例中使用@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

来源 | https://dzone.com/articles/spring-framework-restcontroller-vs-controller

翻译 | laocaicaicai

640?wx_fmt=gif

往期推荐

ES 的分布式架构原理能说一下么?

2020-08-01

0eb2d42c0e255f749c6aa05a47f17f81.png

面试 | 如何从大量的 URL 中找出相同的 URL?

2020-08-02

76140c1bc09e3f19ee9df5c2b7665031.png

一个Java方法能使用多少个类型参数?

2020-07-31

eee2815a570636013117e783fd9d6f2f.png

字符串拼接,什么时候用StringBuilder?

2020-07-30

4032e621defb6f3fc3712e59307fb97d.png

你要知道的 21 道软件设计+面向对象的面试题 · 讨论

2020-07-29

6bf4eaf3beb5b0c38193eae747d8ea21.png

一起进大厂,每日学干货

关注我,不迷路

5574db3ffa1ea7c94556ca9ce5221221.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值