02、SpringMVC核心(上)
一、RequestMapping注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
@Reflective({ControllerMappingReflectiveProcessor.class})
public @interface RequestMapping {String name() default "";@AliasFor("path")String[] value() default {};@AliasFor("value")String[] path() default {};RequestMethod[] method() default {};String[] params() default {};String[] headers() default {};String[] consumes() default {};String[] produces() default {};
}
RequestMapping注解是SpringMVC框架中的一个控制器映射注解,用于把请求映射到相应的处理方法上。也就是说它可以把指定URL的请求绑定到一个特定的方法或类上。从而实现对请求的处理和响应。
其定义中的:@Target({ElementType.TYPE, ElementType.METHOD}) 表明这个注解是可以出现在类或者是方法上的。
RequestMapping映射唯一性
如果我们的项目中有两个不同的处理器方法上使用了相同的映射路径,这会怎么样呢?
示例如下:
@Controller
public class UserController {@RequestMapping("/detail")public String toDetail() {return "detail";}
}
@Controller
public class ProductController {@RequestMapping("/detail")public String toDetail() {return "detail";}
}
这样子是会出问题的,因为当前端请求的路径是/detail的时候到底哪个处理器方法处理并响应?
在程序部署到Tomcat当中的时候会报错如下:
java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'userController' method com.xiaoxie.controller.UserController#toDetail() to { [/detail]}: There is already 'productController' bean method com.xiaoxie.controller.ProductController#toDetail() mapped.
从而我们得出一个结论:在同一个webapp中,RequestMapping必须具有唯一性。对上面的错误我们如何解决?
有两种解决方案:
- 方案一:把方法上RequestMapping的映射路径修改为不一样
- 方案二:在类上也添加上@RequestMapping注解指定映射路径,以类上的这个作为命名空间,用来区分两个不同的映射
解决方案一:
调整两个Controller类如下:
@Controller
public class UserController {@RequestMapping("/user/detail")public String toDetail() {return "user/detail";}
}
@Controller
public class ProductController {@RequestMapping("/product/detail")public String toDetail() {return "product/detail";}
}
这样子的话两个处理类中的toDetial()方法实际上对应的是不同的映射。不会产生冲突
根据上面的两个返回的逻辑视图的名称,根据SpringMVC配置文件要求分别在指定位置建立对应的detail.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>商品详情页</title>
</head>
<body><h1>商品详情</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>用户详情页</title>
</head>
<body><h1>用户详情</h1>
</body>
</html>
解决方案二:
同时在类和方法上都加上@RequestMappping注解来进行路径映射。比如我们在类上映射的路径是/a,在方法上映射的路径是/b,那么完整的映射路径就是"/a/b"
在方案一中,如果我们UserController类中有很多映射处理方法,那么每个方法上都加上"/user",会比较麻烦,这个时候可以考虑把/user提到类上去注解。
@Controller
@RequestMapping("/user")
public class UserController {@RequestMapping("/detail")public String toDetail() {return "user/detail";}
}
@Controller
@RequestMapping("/product")
public class ProductController {@RequestMapping("/detail")public String toDetail() {return "product/detail";}
}
value属性
value属性匹配控制器
value属性是@RequestMapping注解的核心属性,它指定的是请求路径,也就是说通过这个请求路径与对应的控制器方法绑定到一起。
@AliasFor("path")
String[] value() default {};
从上面可以看到为了可读性,value属性与path属性是代表的同一个东西,只是我们只写value属性值是可以省略value这个名称,当我们path属性时则必须把属性名path写上。
另外,属性可配置的值是一个字符串数组,从这里可以看出来在SpringMVC当中多个不同的请求可以映射到同一个控制器的同一方法上。
@Controller
public class TestValueController {@RequestMapping({"/testValue1","/testValue2"})public String testValue() {return "testValue";}
}
value属性值是用来匹配请求路径的,它也支持模糊匹配
我们把这种模糊匹配称为Ant风格,路径中的通配符包含如下一些:
?:表示任意一个字符
*:表示0到n个任意字符
**:表示0到n个任意字符,并且路径是可以出现路径分隔符的
注意:** 通配符在使用时其左右是不可以出现除/以外的其它字符的
示例:
@RequestMapping("/a?b/testValeAnt")
public String testValueAnt() {return "testValueAnt";
}
新增高图模板文件:testValueAnt.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>TestValueAnt</title>
</head>
<body><h1>RequestMapping中的value属性支持模糊匹配</h1>
</body>
</html>
在index.html模板文件中加上如下的链接
<a th:href="@{/a0b/testValeAnt}">value属性支持模糊匹配</a>
启动后返回这个链接是正常的
注意:有些情况我们是无法匹配成功的
- /a?b/testValueAnt 看样子是可以匹配到但是要注意,在浏览器上?后面的部分会认为是请求参数,前面的部分才是访问的路径,此时拿/a去请求是匹配不到的
- /a/b/testValueAnt 这个地址浏览器会直接去请求/a/b/testValueAnt是匹配不到控制器方法的
一定要注意,** 这个两边一定要是/,这个时候可以匹配到多级地址,如果它两个不是/则会失去模糊匹配的效果直接认为请求中就是**
value属性中的路径占位
我们常规的路径请求格式是:uri?name1=value1&name2=value2
除了上面这种常规的请求方式,还有一种RESTful的风格请求格式:uri/value1/value2/value3
原来常规的请求格式我们是把?后的当作为请求参数,它是key=value对的形式,那么RESTful风格的请求如果获取到路径中的请求值?
要获取到请求路径中的值得要把路径使用占位符来表示
@RequestMapping("/login/{username}/{password}")
public String testRESTful(@PathVariable("username") String username,@PathVariable("password") String password) {System.out.println(username + ":" + password);return "testRESTful";
}
从上面可以看到:
- @RequestMapping中value属性占位使用{xxx}形式
- 控制器方法中的形参要使用@PathVariable("xxx")形式,来把形参与路径中的值做绑定
这个时候路径占位符上的{xxx},其中指定的名称要与@PathVariable("xxx")指定的名称保持一致它们才能与对应的形参做绑定
method属性
这个属性是用来指定请求方法的,如:POST请求,GET请求,它们的请求方法分别是POST和GET才能对应上,如果我们后端定义的@RequestMapping中定义的method属性值是POST,而前端使用GET请求,这个时候请求方法就无法匹配了,会出现405错误。
method属性的值也是一个数组,类型是RequestMethod的枚举,它定义的值有:
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
@RequestMapping(value = "/login", method= RequestMethod.POST)
public String login() {return "success";
}
像上面这个控制器处理方法login()要求请求路径是/login,请求方法必须是post
衍生Mapping
我们把不同请求方法都写作一个对应的Mapping注解,可以简化我们去指定method的过程。这样就对应的衍生出了如下几个Mapping注解
衍生注解 | 说明 |
---|---|
@PostMapping | 默认请求方法是POST @PostMapping("/test") 等价于 @RequestMapping(value="/test", method=RequestMethod.POST) |
@GetMapping | 表示方法默认采用GET处理方式 |
@PutMapping | 表示方法默认采用PUT处理方式 |
@DeleteMapiing | 表示方法默认使用DELETE处理方式 |
@PatchMapping | 表示方法默认使用PATCH处理方式 |
实际上衍生出来的Mapping注解就是为了省略去写method而来的。
我们看到有多种不同的请求方式,每种方式又是怎么样的呢?我们简单的来说明一个关于web中的请求方式。
web请求方式
前端向后端请求的时候有九种方式常用见有前五种
请求方式 | 说明 |
---|---|
GET | 获取资源,只能读取数据,不影响数据状态 使用url路径传参或者在http请求头添加参数,服务器返回请求资源 |
POST | 向服务器提交资源,可能会改变数据的状态 通过表单的方式提交请求体,服务端接收到请求后进行数据处理 |
PUT | 更新资源,用于更新指定的资源上内容 通过请求体发送需要更新的全部内容,服务端接收到数据后进行资源替换或修改 |
DELETE | 删除资源 用来删除指定资源,把要删 |
相关文章:
02、SpringMVC核心(上)
一、RequestMapping注解 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Mapping @Reflective({ControllerMappingReflectiveProcessor.class}) public @interface RequestMapping {String name() default "";…...

EasyPlayerPro的同一个组件实例根据url不同展示视频流
效果 学习 url的组成 webrtc://192.168.1.225:8101/index/api/webrtc?applive&stream001&typeplay 协议部分 webrtc://: 这表示使用 WebRTC 协议来进行实时通信。WebRTC 允许浏览器之间直接交换音频、视频和其他数据,而不需要通过中间服务器 主机和端口部分…...

哈希表介绍、实现与封装
哈希表介绍、实现与封装 一、哈希概念二、哈希表实现直接定址法其他映射方法介绍1. 哈希冲突2. 负载因子3. 将关键字转为整数4. 设计哈希函数除法散列法 / 除留余数法乘法散列法全域散列法其他方法 将关键字转为整数处理哈希冲突开放定址法线性探测二次探测双重散列 开放定址法…...

使用vm配置网络
查看本地ip 配置vm网络 配置固定ip vi /etc/sysconfig/network-script/ifcfg-ens33参考 vm使用nat模式,导致vm中docker部署的服务,无法通过局域网中其他机器连接 https://www.cnblogs.com/junwind/p/14345385.html 三张图看懂vm中,三种网…...
OpenStack介绍
OpenStack概述 OpenStack是一个开源的云计算管理平台软件,主要用于构建和管理云计算环境。它允许企业或组织通过数据中心的物理服务器创建和管理虚拟机、存储资源和网络等云计算服务。其核心组件包括计算(Nova)、网络(Neutron)、存储(Cinder、Swift)等。这些组件相互协作…...
力扣93题:复原 IP 地址
力扣93题:复原 IP 地址(C语言实现详解) 题目描述 给定一个只包含数字的字符串 s,复原它并返回所有可能的 IP 地址格式。 有效的 IP 地址需满足以下条件: IP 地址由四个整数(每个整数位于 0 到 255 之间…...

mock.js介绍
mock.js http://mockjs.com/ 1、mock的介绍 *** 生成随机数据,拦截 Ajax 请求。** 通过随机数据,模拟各种场景;不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据;支持生成随机的文本、数字…...

React开发 - 技术细节汇总一
React简介 React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。 ui render (data) -> 单向数据流 MVC // model var myapp {}; // …...

【论文复现】分割万物-SAM
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀ 分割万物-SAM 介绍原理分割任务任务预训练zero-shot transfer相关任务 模型Image EncoderPrompt EncoderMask Eecoder消除歧义高效Loss 和训…...

实现RAGFlow-0.14.1的输入框多行输入和消息框的多行显示
一、Chat页面输入框的修改 1. macOS配置 我使用MacBook Pro,chip 是 Apple M3 Pro,Memory是18GB,macOS是 Sonoma 14.6.1。 2. 修改chat输入框代码 目前RAGFlow前端的chat功能,输入的内容是单行的,不能主动使用Shift…...

Pointnet++改进71:添加LFE模块|高效长距离注意力网络
简介:1.该教程提供大量的首发改进的方式,降低上手难度,多种结构改进,助力寻找创新点!2.本篇文章对Pointnet++特征提取模块进行改进,加入LFE模块,提升性能。3.专栏持续更新,紧随最新的研究内容。 目录 1.理论介绍 2.修改步骤 2.1 步骤一 2.2 步骤二 2.3 步骤三 1.理…...

C++STL容器vector容器大小相关函数
目录 前言 主要参考 vector::size vector::max_size vector::resize vector::capacity vector::empty vector::reserve vector::shrink_to_fit 共勉 前言 本文将讨论STL容器vector中与迭代器相关的函数,模板参数T为int类型。 主要参考 cpluscplus.com 侯…...
阿里云CPU超载解决记录
现象:阿里云CPU使用率超90%连续5分钟告警,项目日志error.log中存在heap/gc/limit等内存耗尽等信息,阿里云慢查询日志每日有查询时间很长的参数一直不变的慢sql,linux服务器使用top命令并按c可以看到cpu过大是哪个命令行造成的 分…...

【工具变量】上市公司企业商业信用融资数据(2003-2022年)
一、测算方式:参考《会计研究》张新民老师的做法 净商业信用NTC(应付账款应付票据预收账款)-(应收账款应收票据预付账款),用总资产标准化; 应付账款AP应付账款应付票据预收账款,用总资产标准化 一年以上应付账款比例LAP是企业一年以上(包括一…...

2024数字科技生态大会 | 紫光展锐携手中国电信助力数字科技高质量发展
2024年12月3日至5日,中国电信2024数字科技生态大会在广州举行,通过主题峰会、多场分论坛、重要签约及合作发布等环节,与合作伙伴共绘数字科技发展新愿景。紫光展锐作为中国电信的战略合作伙伴受邀参会,全面呈现了技术、产品创新进…...
ES语法(一)概括
一、语法 1、请求方式 Elasticsearch(ES)使用基于 JSON 的查询 DSL(领域特定语言)来与数据交互。 一个 ElasticSearch 请求和任何 HTTP 请求一样由若干相同的部件组成: curl -X<VERB> <PROTOCOL>://&l…...

(vue)el-cascader多选级联选择器,值取最后一级的数据
(vue)el-cascader多选级联选择器,取值取最后一级的数据 获取到:[“养殖区”,“鸡棚”,“E5001”] 期望:[“E5001”] 问题: 解决方法 增加change事件方法,处理选中的value值 1.单选 <el-cascaderv-model"tags2":o…...

友思特方案 | 精密制程的光影贴合:半导体制造中的高功率紫外光源
导读 为新能源锂电行业赋能第四站:半导体制造中的高功率紫外光源!稳定输出、灵活控制的曝光设备是新能源/半导体行业高端生产中减少误差、提高效率的核心技术,友思特 ALE 系列 UV LED 紫外光源集合6大优势,为精密制造的健康发展提…...

README写作技巧
做一个项目,首先第一眼看上去要美观,这样才有看下去的动力。做项目亦是如此,如果每一步应付做的话,我想动力也不会太大,最终很大概率会放弃或者进度缓慢。 1.README组成 README是对项目的一个说明,它对观看…...

【密码学】分组密码的工作模式
1.电码本模式(ECB) 优点: 每个数据块独立加密,可并行加密,实现简单。 缺点: 相同明文会产生相同密文,不具备数据完整保护性。 适用于短消息的加密传输 (如一个加密密钥)。 工作流程:用相同的密钥分别对…...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...