当前位置: 首页 > news >正文

SpringBoot之响应的详细解析

2. 响应

前面我们学习过HTTL协议的交互方式:请求响应模式(有请求就有响应)

那么Controller程序呢,除了接收请求外,还可以进行响应。

2.1 @ResponseBody

在我们前面所编写的controller方法中,都已经设置了响应数据。

controller方法中的return的结果,怎么就可以响应给浏览器呢?

答案:使用@ResponseBody注解

@ResponseBody注解:

  • 类型:方法注解、类注解

  • 位置:书写在Controller方法上或类上

  • 作用:将方法返回值直接响应给浏览器

    • 如果返回值类型是实体对象/集合,将会转换为JSON格式后在响应给浏览器

但是在我们所书写的Controller中,只在类上添加了@RestController注解、方法添加了@RequestMapping注解,并没有使用@ResponseBody注解,怎么给浏览器响应呢?

@RestController
public class HelloController {@RequestMapping("/hello")public String hello(){System.out.println("Hello World ~");return "Hello World ~";}
}

原因:在类上添加的@RestController注解,是一个组合注解。

  • @RestController = @Controller + @ResponseBody

@RestController源码:

@Target({ElementType.TYPE})   //元注解(修饰注解的注解)
@Retention(RetentionPolicy.RUNTIME)  //元注解
@Documented    //元注解
@Controller   
@ResponseBody 
public @interface RestController {@AliasFor(annotation = Controller.class)String value() default "";
}

结论:在类上添加@RestController就相当于添加了@ResponseBody注解。

  • 类上有@RestController注解或@ResponseBody注解时:表示当前类下所有的方法返回值做为响应数据

    • 方法的返回值,如果是一个POJO对象或集合时,会先转换为JSON格式,在响应给浏览器

下面我们来测试下响应数据:

@RestController
public class ResponseController {//响应字符串@RequestMapping("/hello")public String hello(){System.out.println("Hello World ~");return "Hello World ~";}//响应实体对象@RequestMapping("/getAddr")public Address getAddr(){Address addr = new Address();//创建实体类对象addr.setProvince("广东");addr.setCity("深圳");return addr;}//响应集合数据@RequestMapping("/listAddr")public List<Address> listAddr(){List<Address> list = new ArrayList<>();//集合对象Address addr = new Address();addr.setProvince("广东");addr.setCity("深圳");
​Address addr2 = new Address();addr2.setProvince("陕西");addr2.setCity("西安");
​list.add(addr);list.add(addr2);return list;}
}

在服务端响应了一个对象或者集合,那私前端获取到的数据是什么样子的呢?我们使用postman发送请求来测试下。测试效果如下:

2.2 统一响应结果

大家有没有发现一个问题,我们在前面所编写的这些Controller方法中,返回值各种各样,没有任何的规范。

如果我们开发一个大型项目,项目中controller方法将成千上万,使用上述方式将造成整个项目难以维护。那在真实的项目开发中是什么样子的呢?

在真实的项目开发中,无论是哪种方法,我们都会定义一个统一的返回结果。方案如下:

前端:只需要按照统一格式的返回结果进行解析(仅一种解析方案),就可以拿到数据。

统一的返回结果使用类来描述,在这个结果中包含:

  • 响应状态码:当前请求是成功,还是失败

  • 状态码信息:给页面的提示信息

  • 返回的数据:给前端响应的数据(字符串、对象、集合)

定义在一个实体类Result来包含以上信息。代码如下:

public class Result {private Integer code;//响应码,1 代表成功; 0 代表失败private String msg;  //响应码 描述字符串private Object data; //返回的数据
​public Result() { }public Result(Integer code, String msg, Object data) {this.code = code;this.msg = msg;this.data = data;}
​public Integer getCode() {return code;}
​public void setCode(Integer code) {this.code = code;}
​public String getMsg() {return msg;}
​public void setMsg(String msg) {this.msg = msg;}
​public Object getData() {return data;}
​public void setData(Object data) {this.data = data;}
​//增删改 成功响应(不需要给前端返回数据)public static Result success(){return new Result(1,"success",null);}//查询 成功响应(把查询结果做为返回数据响应给前端)public static Result success(Object data){return new Result(1,"success",data);}//失败响应public static Result error(String msg){return new Result(0,msg,null);}
}

改造Controller:

@RestController
public class ResponseController { //响应统一格式的结果@RequestMapping("/hello")public Result hello(){System.out.println("Hello World ~");//return new Result(1,"success","Hello World ~");return Result.success("Hello World ~");}
​//响应统一格式的结果@RequestMapping("/getAddr")public Result getAddr(){Address addr = new Address();addr.setProvince("广东");addr.setCity("深圳");return Result.success(addr);}
​//响应统一格式的结果@RequestMapping("/listAddr")public Result listAddr(){List<Address> list = new ArrayList<>();
​Address addr = new Address();addr.setProvince("广东");addr.setCity("深圳");
​Address addr2 = new Address();addr2.setProvince("陕西");addr2.setCity("西安");
​list.add(addr);list.add(addr2);return Result.success(list);}
}

使用Postman测试:

相关文章:

SpringBoot之响应的详细解析

2. 响应 前面我们学习过HTTL协议的交互方式&#xff1a;请求响应模式&#xff08;有请求就有响应&#xff09; 那么Controller程序呢&#xff0c;除了接收请求外&#xff0c;还可以进行响应。 2.1 ResponseBody 在我们前面所编写的controller方法中&#xff0c;都已经设置了…...

redis:四、双写一致性的原理和解决方案(延时双删、分布式锁、异步通知MQ/canal)、面试回答模板

双写一致性 场景导入 如果现在有个数据要更新&#xff0c;是先删除缓存&#xff0c;还是先操作数据库呢&#xff1f;当多个线程同时进行访问数据的操作&#xff0c;又是什么情况呢&#xff1f; 以先删除缓存&#xff0c;再操作数据库为例 多个线程运行的正常的流程应该如下…...

智能优化算法应用:基于动物迁徙算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于动物迁徙算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于动物迁徙算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.动物迁徙算法4.实验参数设定5.算法结果6.…...

illuminate/database 使用 五

之前文章&#xff1a; illuminate/database 使用 一-CSDN博客 illuminate/database 使用 二-CSDN博客 illuminate/database 使用 三-CSDN博客 illuminate/database 使用 四-CSDN博客 一、原生查询 1.1 原理 根据之前内容调用执行的静态类为Illuminate\Database\Capsule\M…...

武汉灰京文化:益智游戏的教育与娱乐完美结合

随着游戏技术的不断发展&#xff0c;益智类游戏正经历着一场革命性的变革&#xff0c;逐渐融合了教育和娱乐的元素。创新的设计和互动方式使得许多益智游戏成为了知识传递和技能训练的有效工具&#xff0c;同时保持了娱乐体验的趣味性。这种教育与娱乐的完美结合不仅使益智游戏…...

arcgis api for js 中的query实现数据查询

相当于服务地址中的query查询 获取图层范围内的数据4.24 import Query from arcgis/core/rest/support/Query; import * as QueryTask from "arcgis/core/rest/query";//获取图层范围内的数据4.24 _returnFeatureFromWhere(url, where, geo) {const self thisretu…...

AcWing 1250. 格子游戏(并查集)

题目链接 活动 - AcWing本课程系统讲解常用算法与数据结构的应用方式与技巧。https://www.acwing.com/problem/content/1252/ 题解 当两个点已经是在同一个连通块中&#xff0c;再连一条边&#xff0c;就围成一个封闭的圈。一般用x * n y的形式将&#xff08;x, y&#xff0…...

CSS对文本的简单修饰

CSS格式&#xff1a; 格式一&#xff1a;在head中的style标签范围内。 < style> 在style内的只写名字不写 &#xff1a; < > 选择器 { 属性的名称 &#xff1a; 样式&#xff1b; 属性的名称&#xff1a;样式&#xff1b; } < style> style中的注释用/* *…...

C++17中if和switch语句的新特性

1.从C17开始&#xff0c;if语句允许在条件表达式里添加一条初始化语句。当仅在if语句范围内需要变量时&#xff0c;使用这种形式的if语句。在if语句的条件表达式里定义的变量将在整个if语句中有效&#xff0c;包括else部分。 std::mutex mx; bool shared_flag true; // guard…...

极坐标下的牛拉法潮流计算57节点MATLAB程序

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 潮流计算&#xff1a; 潮流计算是根据给定的电网结构、参数和发电机、负荷等元件的运行条件&#xff0c;确定电力系统各部分稳态运行状态参数的计算。通常给定的运行条件有系统中各电源和负荷点的功率、枢纽…...

软件设计师——计算机网络(三)

&#x1f4d1;前言 本文主要是【计算机网络】——软件设计师——计算机网络的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1…...

【ArkTS】循环控制与List的使用

ArkTS如何进行循环渲染 现有数据如下 class Item{name:stringimage:Resourceprice:numberdicount:numberconstructor(name:string,image:Resource,price:number,dicount?:number) {this.name namethis.image imagethis.price pricethis.dicount dicount} }private items…...

条款3:尽量使用const

文章目录 const指针和函数声明const修饰指针const修饰函数const修饰容器const应用在函数中 const限定成员函数避免const重载的代码重复总结 const指针和函数声明 const修饰指针 char greeting[] "Hello"; char* p greeting; // non-const 指针,// non-const 数据…...

Chromadb词向量数据库总结

简介 Chroma 词向量数据库是一个用于自然语言处理&#xff08;NLP&#xff09;和机器学习的工具&#xff0c;它主要用于词嵌入&#xff08;word embeddings&#xff09;。词向量是将单词转换为向量表示的技术&#xff0c;可以捕获单词之间的语义和语法关系&#xff0c;使得计算…...

Gin之GORM 操作数据库(MySQL)

GORM 简单介绍 GORM 是 Golang 的一个 orm 框架。简单说&#xff0c;ORM 就是通过实例对象的语法&#xff0c;完成关系型数据库的操作的技术&#xff0c;是"对象-关系映射"&#xff08;Object/Relational Mapping&#xff09; 的缩写。使用 ORM框架可以让我们更方便…...

二十七、读写文件

二十七、读写文件 27.1 文件类QFile #include <QCoreApplication>#include<QFile> #include<QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);QFile file("D:/main.txt");if(!file.open(QIODevice::WriteOnly | QIODe…...

flutter 代码混淆

Flutter 应用混淆&#xff1a; Flutter 应用的混淆非常简单&#xff0c;只需要在构建 release 版应用时结合使用 --obfuscate 和 --split-debug-info 这两个参数即可。 –obfuscate --split-debug-info 用来指定输出调试文件的位置&#xff0c;该命令会生成一个符号映射表。目前…...

05 Vue中常用的指令

概述 All Vue-based directives start with a v-* prefix as a Vue-specific attribute. 所有基于 Vue 的指令都以 v-* 前缀作为 Vue 特有的属性。 v-text The v-text directive has the same reactivity as with interpolation. Interpolation with {{ }} is more perform…...

Mr. Cappuccino的第67杯咖啡——MacOS通过PD安装Win11

MacOS通过PD安装Win11 下载ParallelsDesktop安装ParallelsDesktop激活ParallelsDesktop下载Windows11安装Windows11激活Windows11 下载ParallelsDesktop ParallelsDesktop下载地址 安装ParallelsDesktop 关闭上面的窗口&#xff0c;继续操作 激活ParallelsDesktop 关闭上面的…...

【云原生kubernets】Service 的功能与应用

一、Service介绍 在kubernetes中&#xff0c;pod是应用程序的载体&#xff0c;我们可以通过pod的ip来访问应用程序&#xff0c;但是pod的ip地址不是固定的&#xff0c;这也就意味着不方便直接采用pod的ip对服务进行访问。为了解决这个问题&#xff0c;kubernetes提供了Service资…...

专业级隐私保护工具:Boss-Key老板键完全使用指南

专业级隐私保护工具&#xff1a;Boss-Key老板键完全使用指南 【免费下载链接】Boss-Key 老板来了&#xff1f;快用Boss-Key老板键一键隐藏静音当前窗口&#xff01;上班摸鱼必备神器 项目地址: https://gitcode.com/gh_mirrors/bo/Boss-Key 在现代办公环境中&#xff0c…...

3种方式掌控多显示器亮度:Monitorian让你的Windows屏幕管理更智能

3种方式掌控多显示器亮度&#xff1a;Monitorian让你的Windows屏幕管理更智能 【免费下载链接】Monitorian A Windows desktop tool to adjust the brightness of multiple monitors with ease 项目地址: https://gitcode.com/gh_mirrors/mo/Monitorian 你是否曾为Windo…...

IDEA里配置Druid连接池,别再手动导Jar包了!试试Maven/Gradle一键搞定

IDEA中配置Druid连接池&#xff1a;Maven/Gradle现代化依赖管理实战 在Java开发领域&#xff0c;依赖管理一直是项目构建的重要环节。记得刚入行时&#xff0c;我也曾手动下载各种Jar包&#xff0c;然后在IDE中逐个添加依赖。直到有一天&#xff0c;项目引用的Jar包版本冲突导致…...

Boss-Key:Windows下一键隐藏窗口的终极隐私保护工具

Boss-Key&#xff1a;Windows下一键隐藏窗口的终极隐私保护工具 【免费下载链接】Boss-Key 老板来了&#xff1f;快用Boss-Key老板键一键隐藏静音当前窗口&#xff01;上班摸鱼必备神器 项目地址: https://gitcode.com/gh_mirrors/bo/Boss-Key 在数字化办公时代&#xf…...

星链引擎:AI 驱动的全域营销决策自动化系统技术实现

一、引言在当前数字化营销时代&#xff0c;企业面临着前所未有的数据爆炸和决策复杂度。一个典型的全域营销场景中&#xff0c;企业每天需要处理来自多个平台的数百万条用户行为数据&#xff0c;同时还要根据市场变化、竞品动态和用户反馈&#xff0c;实时调整内容策略、发布策…...

PromethAI-Backend:构建标准化AI智能体后端框架的工程实践

1. 项目概述与核心价值最近在折腾AI应用开发&#xff0c;特别是想搞一个能处理复杂工作流的智能体系统&#xff0c;发现了一个挺有意思的开源项目——PromethAI-Backend。这名字听着就有点“普罗米修斯”盗火种给人类的意思&#xff0c;挺形象的&#xff0c;它本质上就是一个为…...

别再死记硬背了!用Python模拟LDPC和Polar码的编码过程(附代码)

Python实战&#xff1a;用可视化方法理解LDPC与Polar码的核心原理 在无线通信系统的物理层设计中&#xff0c;信道编码技术如同数据的"防弹衣"&#xff0c;保护信息在充满噪声的传输环境中安全抵达。本文将带你用Python构建两种5G核心编码方案——LDPC码和Polar码的简…...

模型服务化部署:用vLLM/Ollama搭建高并发API,支持流式输出与多轮对话

系列导读 你现在看到的是《本地大模型私有化部署与优化:从入门到生产级实战》的第 3/10 篇,当前这篇会重点解决:让你的本地模型像ChatGPT一样提供稳定API,支持真实业务场景的并发请求。 上一篇回顾:第 2 篇《模型下载与转换实战:从HuggingFace到GGUF/SafeTensors,格式…...

两轮车租赁数字化升级:从物联网架构到运营效率提升

1. 两轮车租赁模式升级&#xff1a;从传统痛点看数字化解决方案最近和几个在欧洲做短途出行和即时配送的朋友聊天&#xff0c;大家不约而同地提到了一个趋势&#xff1a;两轮车&#xff0c;特别是电动两轮车的租赁市场&#xff0c;正在经历一场静悄悄但深刻的模式升级。这背后&…...

人机协同中的“因为-所以”、“if-then”(如果-那么)

在人机协同中&#xff0c;“因为-所以”和“if-then”&#xff08;如果-那么&#xff09;是两种截然不同但紧密相关的逻辑范式。简单来说&#xff0c;“if-then”是机器的“计算”语言&#xff0c;而“因为-所以”是人类“算计&#xff08;谋算&#xff09;”与因果推理的核心。…...