Spring MVC(一)
@RestController
@RestController 是由 @Controller 和 @ResponseBody 两个注解构成的。
Spring 启动的时候会扫描所有包含 @Controller 或者 @RestController 注解的类,创建出对外的接口,这样外界就可以从这里与服务器实现交互,如果没有这个注解, Spring 就不会 扫描该类,外界也就无法找到这个类了。
因为 Spring 项目包含的类很多,不仅仅有自定义的类,还有标准库第三方库的类,为了能快速启动 Spring 项目,所以 Spring 只会扫描所有包含 @Controller 或者 @RestController 注解的类,并创建其对外的接口
举个例子:下面的类即使使用了 @RequestMapping 注解,客户端在访问的时候得到却是 404 (页面不存在)的响应,就因为这个类没有使用 @Controller 或者 @RestController 注解


404 页面可以由程序员自行设定,例如 B站的 404 页面就很精美,Spring 的 404 页面有一个默认的页面,上面就是默认的 404 页面
@Controller 和 @ReponseBody的区别:
@Controller 是用来返回页面的,例如 html
@ResponseBody 是用来返回数据的。
如果你在类上面使用了 @Controller ,在类里的方法的返回值就是页面,例如下面所示:返回一个 html 页面,返回值的参数类型虽然是 String,但是Spring 会将返回值作为 html 来解析。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>我是一级标题</h1>
</body>
</html>
@RequestMapping("/RespController")
@Controller
public class ResponseController {@RequestMapping("r1")public String returnHTML() {return "/index.html";}
}
返回页面的时候,返回值填写的是 该页面相对于 static 这个包的路径


通过抓包我们可以看出响应的数据类型为 text/html

由于 @Controller 注解的类的方法一般返回的是页面,如果你想要返回数据的话,可以在方法上加上 注解 @ResponseBody
@ResponseBody@RequestMapping("/r2")public String returnText() {return "/index.html";}

注解源码解析
@RestController 源码解析:

Target 是指这个注解可以作用的位置,ElementType 里面包含很多枚举类型,其中 TYE 指类,说明 @RestController 是一个类注解,作用在类上。
Retention 指注解可以存活到哪个事时间段里:我们编写的Java 代码要运行的时候,首先是由源代码(SOURCE)编译为 .class 文件(CLASS),最后才进入运行阶段(RUNTIME)
@RestController 可以活到 RUNTIME,说明 @RestController 在代码运行阶段依旧存在

接着下面就是我们熟知的 @Controller 和 @ResponseBody 两个注解,这也说明了 @RestController 是 由 @Controller 和 @ResponseBody 两个注解构成的。
Controller 注解源码解析:

首先这是一个类注解,只能作用在类上,不能作用在方法上
其可以存活在代码运行阶段
@ResponseBody 注解源码解析:

即是一个类注解,也是一个方法注解
其可以存活在代码运行阶段
@ResquestMapping
@RequestMapping 是 用来注册接口的路由映射的。
简单来说,@RequestController 是用来开辟一个外界能找到的路径,@RestController 或者 @Controller 就是路径的大门,只有大门打开了,外界才能走这一条路。
在学习 http 的时候,我们知道发送请求的方法有好几种,其中包括 GET、POST、PUT、DELETE…
如果想要让客户端使用指定的请求方法的话,可以使用 @GetMapping、@PostMapping、@PutMapping 等
而 @RequestMapping 则是包含所有的请求方法,即客户端使用哪个请求方法都可以,这个注解我们经常使用
@RequestMapping 即是一个 类注解,也是一个方法注解,访问路径是 类路径 + 方法路径
如果要访问下面类的 r1 方法的话,url 为 http://127.0.0.1:8080/RequestController/r1?a=aaa

在写路径的时候,我们一般把路径名称定义为对应的类名或者方法名,可以不加 /,如果不加 Spring 会默认加上,一般我们都会加上 /
传递普通参数
使用基本类型传参的时候,参数为必传参数(除 boolean 之外),否则会报 500 错误
类型不匹配的时候,会报 400 错误
@RequestMapping("/ResController")
@RestController
public class RequestController {@RequestMapping("r2")public String r2(String a, int b) {return "接收参数:" + a + b;}
}
举个例子:
如果不传递 b 参数(int 类型),就会报错


IDEA 上也会报错:

如果你传递的类型不匹配,会报 400 的错误


IDEA 会提示 String 类型的参数无法传递给 int 类型里。

正常传递参数:


传递多个普通参数
在传递多个参数,只要参数的名称写对即可,不需要考虑顺序,Spring 会根据对应的 参数名区接收参数。
@RequestMapping("/ResController")
@RestController
public class RequestController {@RequestMapping("/r6")public String r6(String name, int gender, int age) {return "接收到的参数:" + "name:" + name + " gender:" + gender + " age:" + age;}
}


传递对象
如果参数比较多的时候,方法的声明就需要很多的形参,并且后续每增加一个新的参数,方法的参数列表也要进行增加,为了方便书写,我们会将这些参数封装成一个对象,Spring MVC 会自动实现对对象参数的赋值
例如我们要传递一个 UserInfo 对象:
public class UserInfo {String name;int gender;int age;public UserInfo() {}public UserInfo(String name, int gender, int age) {this.name = name;this.gender = gender;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getGender() {return gender;}public void setGender(int gender) {this.gender = gender;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "UserInfo{" +"name='" + name + '\'' +", gender=" + gender +", age=" + age +'}';}
}
@RequestMapping("/ResController")
@RestController
public class RequestController {@RequestMapping("/r7")public String r7(UserInfo userInfo) {return userInfo.toString();}
}

如果参数没有写全的话:由于是对象的参数,这些参数有默认值,没有传递的参数,一律使用 默认值,这是 JavaSE 的知识了。

传递数组
@RequestMapping("/ResController")
@RestController
public class RequestController {@RequestMapping("/r9")public String r9(int[] arr) {return Arrays.toString(arr);}
}
在 postman 我们可以一个一个元素去传递

也可以一起传递过去


@RequestParam(参数重命名)
当前端传递的参数和我们后端自己写的参数不符合的时候,我们可以使用 @RequestParam 这个注解来重命名参数,例如:我们方法定义的参数为 name,但是前端想用 a 来进行传递,我们可以将 name 重命名为 a
@RequestMapping("/ResController")
@RestController
public class RequestController {@RequestMapping("/r8")public String r8(@RequestParam(value = "a") String name) {return "接收参数:" + name;}
}

参数进行重命名之后,外界只能使用重命名后的参数名称来传递数值,不可以使用 后端定义的参数名!!!
否则会报 400 的客户端错误


源码解析

@RequsetParam 作用在参数上(PARAMETER)
其中 重命名设置既可以使用 value = “新参数名”,也可以使用 name = “新参数名”
required 是指这个参数是 必传的还是非必传的,@RequestParam 默认是必传参数,如果要设置非必传参数需要单独设置 required = false
必传参数与非必传参数
如果有写参数是可以不用传递的话,我们可以设置为非必传参数,这样没有传递参数也不会发生报错,没有传递参数会默认赋值为 默认值,所以基本类型的参数即使设置为 非必传参数也没用,基本类型的参数一定的必传的参数,否则就会发生报错。
非必传参数设置为 required = false
@RequestMapping("/ResController")
@RestController
public class RequestController {@RequestMapping("/r11")public String r11(@RequestParam(value = "s", required = false) String str) {return str + " test";}@RequestMapping("/r12")public int r12(@RequestParam(value = "a", required = false) int aaaa) {return aaaa;}
}
设置为非必传参数,在没有传递参数的话,会设置为默认值。

基本类型的参数就算设置为非必传参数也没用,没有传递依旧报错

传递集合
在参数传递的形式上,集合参数的传递和上面数组参数传递是一样的。
但是需要 使用 @RequestParam 注解来绑定参数关系
默认情况下,请求中参数名称相同的多个值是封装到数组里的,如果要封装到集合中,需要使用 @RequestParam 绑定参数关系
@RequestMapping("/ResController")
@RestController
public class RequestController {@RequestMapping("/r10")public String r10(@RequestParam List<Integer> list) {return list.toString();}
}


JSON
JSON 介绍
JSON 和 JS 没有关系,只是语法相似。
JSON 本质上就是一个字符串,通过文本来存储和描述数据
Spring MVC 有 JSON 转换工具,我们可以直接使用,以此来完成JSON 和 Java对象的互传,当然网络上也有很多 JSON 转换工具,我们都可以直接拿来使用。
JSON 语法:
使用键值对(key,value)保存数据
数据与数据之间使用 , 分割
对象使用 { } 表示
数组使用 [ ] 表示
数值可以为对象,也可以为数组,数组中可以包含多个对象。
举例:下面的格式化的 JSON 数据:
{"squadName": "Super hero squad","homeTown": "Metro City","formed": 2016,"secretBase": "Super tower","active": true,"members": [{"name": "Molecule Man","age": 29,"secretIdentity": "Dan Jukes","powers": ["Radiation resistance", "Turning tiny", "Radiationblast "]},{"name": "Madame Uppercut","age": 39,"secretIdentity": "Jane Wilson","powers": ["Million tonne punch", "Damage resistance", "Superhumanreflexes "]},{"name": "Eternal Flame","age": 1000000,"secretIdentity": "Unknown","powers": ["Immortality", "Heat Immunity", "Inferno","Teleportation", "Interdimensional travel"]}]
}
也可以进行压缩然后表示:
{"squadName":"Super hero squad","homeTown":"Metro City","formed":2016,"secretBase":"Super tower","active":true,"members":[{"name":"Molecule Man","age":29,"secretIdentity":"Dan Jukes","powers":["Radiation resistance","Turning tiny","Radiationblast "]},{"name":"Madame Uppercut","age":39,"secretIdentity":"Jane Wilson","powers":["Million tonne punch","Damage resistance","Superhumanreflexes "]},{"name":"Eternal Flame","age":1000000,"secretIdentity":"Unknown","powers":["Immortality","Heat Immunity","Inferno","Teleportation","Interdimensional travel"]}]}
JSON 传递 (@RequestBody)
使用 @RequestBody 来绑定参数,RequestBody 是 作用在请求正文的数据绑定,请求参数必须写在请求正文中.
我们将 UserInfo 这个对象使用 JSON 格式的数据进行传递
public class UserInfo {String name;int gender;int age;public UserInfo() {}public UserInfo(String name, int gender, int age) {this.name = name;this.gender = gender;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getGender() {return gender;}public void setGender(int gender) {this.gender = gender;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "UserInfo{" +"name='" + name + '\'' +", gender=" + gender +", age=" + age +'}';}
}
@RequestMapping("/ResController")
@RestController
public class RequestController {@RequestMapping("/r13")public String r13(@RequestBody UserInfo userInfo) {return userInfo.toString();}
}
在 postman 中选择 raw ,选择 JSON ,然后填写你要传递的 JSON 数据

在传递对象的参数使用 JSON 时,如果缺少默写参数,会使用参数的默认值进行填充,和之前我们提到的是一样的。

从 URL 获取参数 @PathVariable
如果方法参数名和需要绑定的URL中的变量名称一致时,可以不进行重命名
如果方法参数名和需要绑定的URL中的变量名称不一致的时候,需要进行重命名

将你要从URL获取的参数使用 { } 包裹起来,需要重命名的参数直接在 @PathVariable 里面填写即可。
@RequestMapping("/ResController")
@RestController
public class RequestController {@RequestMapping("/r14/{id}/{name}")public String r14(@PathVariable Integer id, @PathVariable("name") String userName) {return "id = " + id + " name = " + userName;}
}


上传文件 @RequestPart
@RequestMapping("/r15")public String getFile(@RequestPart("file1") MultipartFile file) throws IOException {System.out.println(file.getOriginalFilename());//文件上传file.transferTo(new File("D:\\图\\" + file.getOriginalFilename()));return "文件上传成功!";}


查看电脑对应的路径,发现文件成功接收并下载到对应的路径里。

相关文章:
Spring MVC(一)
RestController RestController 是由 Controller 和 ResponseBody 两个注解构成的。 Spring 启动的时候会扫描所有包含 Controller 或者 RestController 注解的类,创建出对外的接口,这样外界就可以从这里与服务器实现交互,如果没有这个注解…...
vue3使用tsx渲染复杂逻辑的表单
前置 目前的应用场景是:检查项目是树结构,有的项目还需要动态显示对应的子集 项目用的是uniappvue3tsvite生成的app tsx模版 统一渲染入口 <script lang"ts">import uniForms from dcloudio/uni-ui/lib/uni-forms/uni-forms.vueimport…...
python助力WRF自动化运行
对大部分人而言,特别是新用户,WRF模式的安装繁琐且不必要,可以作为后续进阶掌握的技能,本学习跳过繁琐的安装步骤,直接聚焦模式的运行部分,通过短平快的教学,快速掌握模式运行。进一步将python语…...
Windows 下 Postgres 安装 TimescaleDB 插件
Windows 下 Postgres 安装 TimescaleDB 插件 一、准备工作 安装 PostgreSQL:首先确保你已经在 Windows 系统中成功安装了 PostgreSQL 数据库。可以从 PostgreSQL 官方网站下载适合你系统的安装包,并按照安装向导进行安装。安装过程中,记住设…...
【Vim Masterclass 笔记21】S09L39:Vim 设置与 vimrc 文件的用法示例(二)
文章目录 S09L39 Vim Settings and the Vimrc File - Part 21 Vim 的配色方案与 color 命令2 map 命令3 示例:用 map 命令快速生成 HTML 代码片段4 Vim 中的 Leader 键5 用 mkvimrc 命令自动生成配置文件 写在前面 本篇为 Vim 自定义配置的第二部分。当中的每个知识…...
【Docker】Supervisor 实现单容器运行多服务进程
本文内容均来自个人笔记并重新梳理,如有错误欢迎指正! 如果对您有帮助,烦请点赞、关注、转发、订阅专栏! 专栏订阅入口 | 精选文章 | Kubernetes | Docker | Linux | 羊毛资源 | 工具推荐 | 往期精彩文章 【Docker】(全…...
【网络协议】【http】【https】ECDHE-TLS1.2
【网络协议】【http】【https】ECDHE-TLS1.2 ECDHE算法 1.客户端和服务器端事先确定好使用哪种椭圆曲线,和曲线上的基点G,这两个参数都是公开的, 双方各自随机生成一个随机数作为私钥d,并与基点 G相乘得到公钥Q(QdG),…...
(十五)WebGL中gl.texImage2D函数使用详解
在 WebGL 中,gl.texImage2D 是一个非常关键的函数,用于将图像数据上传到 WebGL 上下文中并作为纹理对象的一部分。它允许你将图像、视频、画布等作为纹理源。理解如何使用 gl.texImage2D 是在 WebGL 中处理纹理的核心之一。 文章目录 gl.texImage2D 的基…...
CSS 颜色
所有浏览器都支持的颜色名 所有现代浏览器均支持以下 140 种颜色名称(单击颜色名称或十六进制值,可查看将以该颜色为背景颜色以及不同的文本颜色): 颜色名十六进制颜色值颜色AliceBlue#F0F8FFAntiqueWhite#FAEBD7Aqua#00FFFFAqu…...
C#,入门教程(03)——Visual Studio 2022编写彩色Hello World与动画效果
C#,入门教程(01)—— Visual Studio 2022 免费安装的详细图文与动画教程https://blog.csdn.net/beijinghorn/article/details/123350910 C#,入门教程(02)—— Visual Studio 2022开发环境搭建图文教程https://blog.csdn.net/beijinghorn/article/detail…...
杀死安装 CentOS-7-x86_64-DVD-1908
使用 VMware 安装 CentOS-7-x86_64-DVD-1908 CentOS是 reahat 的 免费版本,有了ubutun ,为什么还要使用 CentOS呢? 在linux 服务器实际开发中,大家都用的CentOS,因为两个原因,一个是免费,第二是…...
55.【5】BUUCTF WEB NCTF2019 sqli
进入靶场 输入admin 123 过滤的这么严格??? 过滤很严格,此时要么爆破,要么扫描 直接扫描,得到robots.txt 访问后又得到hint.txt 继续访问 图片内容如下 $black_list "/limit|by|substr|mid|,|admi…...
LeetCode 题目 2545. 根据第 K 场考试的分数排序
在本篇文章中,我们将探讨如何根据第 K 场考试的分数对学生进行排序。这个问题是 LeetCode 上的一个中等难度问题,涉及到排序算法和自定义比较函数的使用。 问题描述 解题思路 理解问题 首先,我们需要理解问题的核心:根据第 K 场…...
算法随笔_12:最短无序子数组
上一篇: 算法随笔_11: 字符串的排列-CSDN博客 题目描述如下: 给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。请你找出符合题意的最短子数组,并输出它的长度。…...
计算机毕业设计PySpark+Hadoop+Hive机票预测 飞机票航班数据分析可视化大屏 航班预测系统 机票爬虫 飞机票推荐系统 大数据毕业设计
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Linux-C/C++--初探linux应用编程概念
对于大多数首次接触 Linux 应用编程的读者来说,可能对应用编程(也可称为系统编程)这个概念并不 太了解,所以在正式学习 Linux 应用编程之前,笔者有必要向大家介绍这些简单基本的概念,从整体上认识 到应用编…...
用sklearn运行分类模型,选择AUC最高的模型保存模型权重并绘制AUCROC曲线(以逻辑回归、随机森林、梯度提升、MLP为例)
诸神缄默不语-个人CSDN博文目录 文章目录 1. 导入包2. 初始化分类模型3. 训练、测试模型,绘图,保存指标 1. 导入包 from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier, GradientBoostingClass…...
动手学大数据-3社区开源实践
目录 数据库概览: MaxComput: HAWQ: Hologres: TiDB: Spark: ClickHouse: Apache Calcite 概览 Calcite RBO HepPlanner 优化规则(Rule) 内置有100优化规则 …...
使用Pydantic驾驭大模型
本文介绍Pydantic 库,首先介绍其概念及优势,然后通过基本示例展示如何进行数据验证。后面通过多个示例解释如何在LangChain中通过Pydantic进行数据验证,保证与大模型进行交互过程中数据准确性,并显示清晰的数验证错误信息。 Pydan…...
【HarmonyOS之旅】基于ArkTS开发(二) -> UI开发之常见布局
目录 1 -> 自适应布局 1.1 -> 线性布局 1.1.1 -> 线性布局的排列 1.1.2 -> 自适应拉伸 1.1.3 -> 自适应缩放 1.1.4 -> 定位能力 1.1.5 -> 自适应延伸 1.2 -> 层叠布局 1.2.1 -> 对齐方式 1.2.2 -> Z序控制 1.3 -> 弹性布局 1.3.1…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
