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

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>

启动后返回这个链接是正常的

注意:有些情况我们是无法匹配成功的

  1. /a?b/testValueAnt   看样子是可以匹配到但是要注意,在浏览器上?后面的部分会认为是请求参数,前面的部分才是访问的路径,此时拿/a去请求是匹配不到的
  2. /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 允许浏览器之间直接交换音频、视频和其他数据&#xff0c;而不需要通过中间服务器 主机和端口部分…...

哈希表介绍、实现与封装

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

使用vm配置网络

查看本地ip 配置vm网络 配置固定ip vi /etc/sysconfig/network-script/ifcfg-ens33参考 vm使用nat模式&#xff0c;导致vm中docker部署的服务&#xff0c;无法通过局域网中其他机器连接 https://www.cnblogs.com/junwind/p/14345385.html 三张图看懂vm中&#xff0c;三种网…...

OpenStack介绍

OpenStack概述 OpenStack是一个开源的云计算管理平台软件,主要用于构建和管理云计算环境。它允许企业或组织通过数据中心的物理服务器创建和管理虚拟机、存储资源和网络等云计算服务。其核心组件包括计算(Nova)、网络(Neutron)、存储(Cinder、Swift)等。这些组件相互协作…...

力扣93题:复原 IP 地址

力扣93题&#xff1a;复原 IP 地址&#xff08;C语言实现详解&#xff09; 题目描述 给定一个只包含数字的字符串 s&#xff0c;复原它并返回所有可能的 IP 地址格式。 有效的 IP 地址需满足以下条件&#xff1a; IP 地址由四个整数&#xff08;每个整数位于 0 到 255 之间…...

mock.js介绍

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

React开发 - 技术细节汇总一

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

【论文复现】分割万物-SAM

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀ 分割万物-SAM 介绍原理分割任务任务预训练zero-shot transfer相关任务 模型Image EncoderPrompt EncoderMask Eecoder消除歧义高效Loss 和训…...

实现RAGFlow-0.14.1的输入框多行输入和消息框的多行显示

一、Chat页面输入框的修改 1. macOS配置 我使用MacBook Pro&#xff0c;chip 是 Apple M3 Pro&#xff0c;Memory是18GB&#xff0c;macOS是 Sonoma 14.6.1。 2. 修改chat输入框代码 目前RAGFlow前端的chat功能&#xff0c;输入的内容是单行的&#xff0c;不能主动使用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中与迭代器相关的函数&#xff0c;模板参数T为int类型。 主要参考 cpluscplus.com 侯…...

阿里云CPU超载解决记录

现象&#xff1a;阿里云CPU使用率超90%连续5分钟告警&#xff0c;项目日志error.log中存在heap/gc/limit等内存耗尽等信息&#xff0c;阿里云慢查询日志每日有查询时间很长的参数一直不变的慢sql&#xff0c;linux服务器使用top命令并按c可以看到cpu过大是哪个命令行造成的 分…...

【工具变量】上市公司企业商业信用融资数据(2003-2022年)

一、测算方式&#xff1a;参考《会计研究》张新民老师的做法 净商业信用NTC(应付账款应付票据预收账款)-(应收账款应收票据预付账款)&#xff0c;用总资产标准化; 应付账款AP应付账款应付票据预收账款&#xff0c;用总资产标准化 一年以上应付账款比例LAP是企业一年以上(包括一…...

2024数字科技生态大会 | 紫光展锐携手中国电信助力数字科技高质量发展

2024年12月3日至5日&#xff0c;中国电信2024数字科技生态大会在广州举行&#xff0c;通过主题峰会、多场分论坛、重要签约及合作发布等环节&#xff0c;与合作伙伴共绘数字科技发展新愿景。紫光展锐作为中国电信的战略合作伙伴受邀参会&#xff0c;全面呈现了技术、产品创新进…...

ES语法(一)概括

一、语法 1、请求方式 Elasticsearch&#xff08;ES&#xff09;使用基于 JSON 的查询 DSL&#xff08;领域特定语言&#xff09;来与数据交互。 一个 ElasticSearch 请求和任何 HTTP 请求一样由若干相同的部件组成&#xff1a; curl -X<VERB> <PROTOCOL>://&l…...

(vue)el-cascader多选级联选择器,值取最后一级的数据

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

友思特方案 | 精密制程的光影贴合:半导体制造中的高功率紫外光源

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

README写作技巧

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

【密码学】分组密码的工作模式

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

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...