Spring MVC:设置响应

目录

引言

1. 返回静态页面

1.1 Spring 默认扫描路径

1.2 @RestController

1.2.1 @Controller => 返回页面

1.2.2 @ResponseBody

2. 返回 HTML

2.1 @RequestMapping

2.1.1 produces(修改响应的 Content-Type)

 2.1.2 其他属性

3. 返回 JSON

4. 设置状态码

4.1 HttpServletResponse

5. 设置 Header 


引言

前面的几篇博文中, 介绍的都是和请求相关的内容, 通过 Spring 的方法来接收请求中相关信息.

本篇博客介绍响应相关的知识, 通过 Spring 来设置响应中的值, 向客户端返回设置好的响应.

1. 返回静态页面

我们首先使用 html 写一个前端页面, 再通过 Spring 方法, 将这个 html 页面作为响应的内容, 展示给用户.

显然, 方法返回的只是一个字符串, 并非 html 展示的页面.

如何将 html 页面返回给客户端呢?? 这需要修改 类注解.

若方法返回的是一个页面, 则需要将原来的类注解 @RestController 修改为 @Controller.

接下来, 对涉及到的几个注解逐个进行解释.

1.1 Spring 默认扫描路径

我们知道, 每一个路径, 都对应了一个方法. 当服务器收到客户端的请求时, Spring 就会根据请求中的资源路径, 寻找该路径对应的方法, 进而计算响应结果, 最后返回响应.

而 Spring 中有大量的方法存在, 包括使用 Maven 引入的第三方库, 都存在于 Spring 中. 若 Spring 要扫描所有的方法, 一个一个的去进行比对, 确定哪个是资源路径所对应的方法的话, 那工作量是巨大的.

因此, Spring 有一个默认扫描路径: 只扫描启动类所在的目录, 及其子目录.

若请求中资源路径对应的方法, 属于启动类所在目录或子目录时, 会被 Spring 扫描到:

而当请求中资源路径所对应的方法, 不属于启动类所在目录或子目录时, 则 Spring 不会扫描, 客户端就会显示错误:

因此, Spring 也当然不会扫描 Maven 中第三方库中的方法.

有了默认的扫描路径, 大大降低了 Spring 的工作量, 提升了开发效率.

1.2 @RestController

虽然 Spring 有默认的扫描路径, 但是当项目很大时, 这个路径下也是会有很多的方法存在的.

于是, 可以使用 @RestController 对类进行标记, Spring 只需扫描被 @RestController 标记的类.

因此, Spring 的扫描对象为: 默认扫描路径中的类 && 使用 @RestController 进行标记的类

当默认路径下的类没有使用 @RestController 进行标记时, 那么 Spring 也不会进行扫描, 进一步减少了 Spring 的工作量.

@RestController 的特性如下:

  1. 类注解. 只能对类进行使用
  2. 存活于运行阶段. (整个项目运行时, 都存在)
  3. 包含 @Controller 和 @ResponseBody

其中, @Controller 表示返回的是页面. @ResponseBody 表示返回的是数据.

@RestController 也表示返回的是数据.

由于 @RestController = @Controller + @ResponseBody, 因此, 左右两侧的注解效果相同:

1.2.1 @Controller => 返回页面

@Controller 是一个类注解(只能给类使用), 并且使用此注解标记类时, 表示该类中的所有方法(@ResponseBody 标记的方法除外, 见下文), 返回的均是页面.

因此, 我们将类的注释修改为 @Controller, 就可以返回静态页面了:

Spring 会以 resources.static 为该 html 文件的基准路径, 扫描指定路径下的 html 文件, 并返回该 html 构造的页面. 并且, html 文件的路径前要加上 /

不过, 现在后端已经基本不会返回页面了.

@RequestMapping("/resp")
@Controller // 表示类中的方法只能返回页面
public class RespController {@ResponseBody // 该方法可以返回数据@RequestMapping("/r1")public String returnPage() {// 返回页面时, 一定要加上 /return "/index.html";}
}

1.2.2 @ResponseBody

@ResponseBody 既是一个类注解, 也是一个方法注解, 表示返回的是数据.

当类注解为 @Controller 时, 类中的方法只能返回页面, 若此时我们想返回数据, 可以对方法使用 @ResponseBody 进行标记, 被标记的方法可以返回数据.

综上, @RestController, @Controller, @ResponseBody 的使用场景如下:

  1. 一个类中, 既有返回页面的方法, 也有返回数据的方法 ==> 使用 @Controller 对类标记, 对返回数据的方法使用 @ResponseBody 标记.
  2. 如果一个类中所有的方法, 返回的都是数据 ==> 使用 @RestController 或者 @Controller + @ResponseBody 对类标记
  3. 如果一个类中所有的方法, 返回的都是页面 ==> 使用 @Controller 对类标记
  4. 类必须有 @Controller 注解才能被 Spring 扫描到(@RestController 包含了 @Controller)

2. 返回 HTML

默认情况下, 响应中的 Content-Type 都是 test/html, 因此, 浏览器收到数据后, 都会按照 html 的格式来解析, 最终展示在页面上.

因此, 如果我们想要给客户端返回一个 HTML 片段, 那我们无需任何操作, 直接返回 HTML 代码即可.

// 返回 HTML 片段@ResponseBody@RequestMapping("/r3")public String returnHTML() {return "<h1>这是一个一级标题</h1>";}

2.1 @RequestMapping

@RequestMapping 是一个类注解, 也是一个方法注解, 既可以对类设置路径, 也可以对方法设置路径.

此外, @RequestMapping 还有一些属性.

2.1.1 produces(修改响应的 Content-Type)

但是, 如果我们想要把这个 HTML 代码, 当做一个普通的字符串去返回, 该怎么办呢?

显然, 我们将响应的 Content-Type 类型修改为纯文本格式即可, 即: test/plain

我们可以通过修改 @RequestMapping 中的 produces 属性, 来修改 Content-Type:

这样, 浏览器接收响应后, 就会将 Body 中的内容, 以纯文本的格式来解析, 而不是当做 HTML .

    // 返回纯文本@ResponseBody@RequestMapping(value = "/r4", produces = "text/plain") // 修改 Content-Type 为纯文本格式public String returnText() {// 当成普通字符串返回return "<h1>这是一个一级标题</h1>";}

 2.1.2 其他属性

@RequestMapping 中不仅有 produces 这一属性, 还有其他属性. 通过设置这些属性值, 可以对请求或者响应中的内容做出要求:

  1. method: 要求请求的方法必须是什么(如:GET, POST, ....), 否则不处理
  2. params: 要求请求中必须包含哪些参数, 否则不处理
  3. headers: 要求请求的 header 中必须包含哪些 header 信息, 否则不处理
  4. consumes: 要求请求的 Content-Type 必须是什么, 否则不处理
  5. produces: 设置响应的 Content-Type 


3. 返回 JSON

Spring 会根据返回数据的类型, 自动对 Content-Type 进行类型的转换.

上文提到, 当返回的数据是字符串时, 默认的 Content-Type 是 text/html; 若想改成其他类型, 还需要手动进行转换.

但是当我们返回的数据是一个对象时(自定义类对象, List 对象, Map 对象, ....), Spring 都会自动将这个对象序列化为 JSON 格式, 并自动将 Content-Type 转换为 application/json:

    // 返回 JSON@ResponseBody@RequestMapping("/r5")public UserInfo returnJson() {// 若返回的数据是一个对象// Spring 会自动将响应中的 Content-Type 转换为 JSON 格式return new UserInfo("dings", "aaa", 1);}

4. 设置状态码

4.1 HttpServletResponse

在后端的 Spring 项目中, 我们既可以通过 HttpServletRequest 来获取请求中的信息, 同样也可以通过 HttpServletResponse 来设置响应中的信息.

因此, 我们可以拿到 HttpServletResponse 对象, 进而通过 setStatus 方法修改响应中的状态码:

    // 设置状态码@ResponseBody@RequestMapping("/r6")public String setStatus(HttpServletResponse response) {// 手动将响应中的状态码设置为 404response.setStatus(404);return "设置状态码成功!!";}

注意: 状态码不影响页面的展示!!

不管状态码是什么, 都可以返回我们自定义的内容. 至于为什么有些网站的 404 页面是一些提示内容, 因为那个界面也是维护那个网站的程序员自己代码写的.

程序员当然也可以将 404 页面打扮的很漂亮!! 比如 bilibili:


5. 设置 Header 

后端可以设置响应中的 header, 通过 header 来向客户端传递一些信息.

仍然是通过 HttpServletResponse 设置响应中的 header:
(header 是以键值对的形式存储数据的)

    // 设置 header@ResponseBody@RequestMapping("/r7")public String setHeader(HttpServletResponse response) {response.setHeader("myHeader", "hahaha");return "设置 header 成功!!";}

END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/67765.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于python+Django+mysql鲜花水果销售商城网站系统设计与实现

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育、辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

提示词的艺术----AI Prompt撰写指南(个人用)

提示词的艺术 写在前面 制定提示词就像是和朋友聊天一样&#xff0c;要求我们能够清楚地表达问题。通过这个过程&#xff0c;一方面要不断练习提高自己地表达能力&#xff0c;另一方面还要锻炼自己使用更准确精炼的语言提出问题的能力。 什么样的提示词有用&#xff1f; 有…

Spring Boot自动配置原理:如何实现零配置启动

引言 在现代软件开发中&#xff0c;Spring 框架已经成为 Java 开发领域不可或缺的一部分。而 Spring Boot 的出现&#xff0c;更是为 Spring 应用的开发带来了革命性的变化。Spring Boot 的核心优势之一就是它的“自动配置”能力&#xff0c;它极大地简化了 Spring 应用的配置…

大模型GUI系列论文阅读 DAY2续2:《使用指令微调基础模型的多模态网页导航》

摘要 自主网页导航的进展一直受到以下因素的阻碍&#xff1a; 依赖于数十亿次的探索性交互&#xff08;通常采用在线强化学习&#xff09;&#xff0c;依赖于特定领域的模型设计&#xff0c;难以利用丰富的跨领域数据进行泛化。 在本研究中&#xff0c;我们探讨了基于视觉-语…

在视频汇聚平台EasyNVR平台中使用RTSP拉流的具体步骤

之前有用户反馈&#xff0c;在EasyNVR平台中添加Pull时使用海康设备的RTSP流地址无法播放。经过研发的优化及一系列严谨的验证流程&#xff0c;我们已确认优化后的EasyNVR平台&#xff0c;通过Pull方式添加海康设备的RTSP流已经能够正常播放。以下是具体的操作步骤&#xff1a;…

Debezium日常分享系列之:对于从Oracle数据库进行快照的性能优化

Debezium日常分享系列之&#xff1a;对于从Oracle数据库进行快照的性能优化 源数据库Kafka Connect监控测试结果 源数据库 Oracle 19c&#xff0c;本地&#xff0c;CDB数据库主机的I/O带宽为6 GB/s&#xff0c;由此主机上运行的所有数据库共享临时表空间由42个文件组成&#x…

C++书籍 第一部分专业C++程序设计概述

1&#xff0c;必不可少的“hello world” #include<iostream>int main(int argc, char** argv) {std::cout << "hello world" << std::endl;return 0; } 这个是一个极其简单的程序&#xff0c;虽然没有多大简直&#xff0c;但是可以体现c程序格式方…

VIVADO ILA IP进阶使用之任意设置ILA的采样频率

VIVADO ILA IP进阶使用之任意设置ILA的采样频率 VIVADO ILA IP和VIO IP结合使用任意设置ILA的采样频率 目录 前言 一、VIO IP的配置 二、ILA IP的配置 三、测试代码 四、测试结果 总结 前言 VIVADO中编写完程序上板测试时经常会用到viavdo自带的ILA逻辑分析仪IP核&#x…

spring @EnableAspectJAutoProxy @Aspect的使用和源码流程

目录 测试代码EnableAspectJAutoProxyAspectJAutoProxyRegistrarAnnotationAwareAspectJAutoProxyCreatororg.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors 实例化AnnotationAwareAspectJAutoProxyCreator bean "a"的代理…

【BUUCTF】[GXYCTF2019]BabySQli

进入页面如下 尝试万能密码注入 显示这个&#xff08;qyq&#xff09; 用burp suite抓包试试 发现注释处是某种编码像是base编码格式 MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5 可以使用下面这个网页在线工具很方便…

重生之我在异世界学编程之算法与数据结构:深入堆篇

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 正文一、堆的基本概念二、堆的存储表示三…

《自动驾驶与机器人中的SLAM技术》ch8:基于预积分和图优化的紧耦合 LIO 系统

目录 1 预积分 LIO 系统的经验 2 预积分图优化的顶点 3 预积分图优化的边 3.1 NDT 残差边&#xff08;观测值维度为 3 维的单元边&#xff09; 4 基于预积分和图优化 LIO 系统的实现 4.1 IMU 静止初始化 4.2 使用预积分预测 4.3 使用 IMU 预测位姿进行运动补偿 4.4 位姿配准部…

软件测试—— 接口测试(HTTP和HTTPS)

软件测试—— 接口测试&#xff08;HTTP和HTTPS&#xff09; HTTP请求方法GET特点使用场景URL结构URL组成部分URL编码总结 POST特点使用场景请求结构示例 请求标头和响应标头请求标头&#xff08;Request Headers&#xff09;示例请求标头 响应标头&#xff08;Response Header…

【Excel超实用,VLOOKUP函数,通过excel数据精准匹配,将一个excel文件的某列数据,用另一个excel文件快速填充】

1、使用背景 如下图1所示&#xff0c;1.xlsx文件&#xff0c;有两列数据&#xff0c;一列序号&#xff0c;一列内容&#xff0c; 我现在需要将第二列的内容快速完成填充&#xff0c;并且有相应的excel模板作为参照。 图1 如图2所示&#xff0c;2.xlsx是模板文件&#xff0c;序…

Transformer详解:Attention机制原理

前言 Hello&#xff0c;大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者&#xff0c;本系列文章是作者参加DataWhale2025年1月份学习赛&#xff0c;旨在讲解Transformer模型的理论和实践。&#x1f632; 本文将详细探讨Attention机制的原理…

PyTorch使用教程(14)-如何正确地选择损失函数?

在机器学习和深度学习的广阔领域中&#xff0c;损失函数&#xff08;Loss Function&#xff09;扮演着至关重要的角色。它不仅是衡量模型预测结果与实际数据之间差异的关键指标&#xff0c;还是指导模型优化方向、影响最终性能的核心要素。选择合适的损失函数&#xff0c;对于提…

P1825 [USACO11OPEN] Corn Maze S 刷题笔记

P1825 [USACO11OPEN] Corn Maze S - 洛谷 | 计算机科学教育新生态 定义状态空间 结构体 精简代码 遇到多种情况判断不要全写进check里面 分开写 传送门是大写字母 A-z 其acll码值 是 65-90 我们将传送门代表的字母-65 就可以将其值映射到 0-26 从而存下相应的传送门坐标…

01设计模式(D3_设计模式类型 - D3_行为型模式)

目录 一、模版方法模式 1. 基本介绍 2. 应用案例一&#xff1a;豆浆制作问题 需求 代码实现 模板方法模式的钩子方法 3. View的draw&#xff08;Android&#xff09; Android中View的draw方法就是使用了模板方法模式 模板方法模式在 Spring 框架应用的源码分析 知识小…

Nginx在Linux中的最小化安装方式

1. 安装依赖 需要安装的东西&#xff1a; wget​&#xff0c;方便我们下载Nginx的包。如果是在Windows下载&#xff0c;然后使用SFTP上传到服务器中&#xff0c;那么可以不安装这个软件包。gcc g​&#xff0c;Nginx是使用C/C开发的服务器&#xff0c;等一下安装会用到其中的…

nacos2.3.0 接入pgsql或其他数据库

首先尝试使用官方插件进行扩展&#xff0c;各种报错后放弃&#xff0c;不如自己修改源码吧。 一、官方解决方案 1、nocos 文档地址&#xff1a;Nacos 配置中心简介, Nacos 是什么 | Nacos 官网 2、官方解答&#xff1a;nacos支持postgresql数据库吗 | Nacos 官网 3、源码下载地…