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…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...

数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...

Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...