【Spring】Spring MVC 程序开发
Spring MVC 程序开发
- 一. 什么是 Spring MVC
- 1. MVC
- 2. Spring、Spring Boot 与 Spring MVC
- 二. 创建 Spring MVC 项目
- 1. 创建项目
- 2. 用户和程序的映射
- 3. 获取用户请求参数
- ①. 获取单个参数
- ②. 获取多个参数
- ③. 传递对象
- ④. 后端参数重命名(后端参数映射)@RequestParam
- ⑤. @RequestBody 接收JSON对象
- ⑥. 获取URL中参数 @PathVariable
- ⑦. 上传文件 @RequestPart
- ⑧. 获取Cookie
- ⑨. 获取 Session
- ⑩. 获取 header
- 4. 返回数据
- ① 返回静态页面
- ②. 返回 text/html
- ③. 返回 JSON 对象
- ④. 请求转发或请求重定向
一. 什么是 Spring MVC
1. MVC
- Model(模型)是应⽤程序中⽤于处理应⽤程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
- View(视图)是应⽤程序中处理数据显示的部分。通常视图是依据模型数据创建的。
- Controller(控制器)是应⽤程序中处理⽤户交互的部分。通常控制器负责从视图读取数据,控制⽤户输⼊,并向模型发送数据。
MVC 是⼀种思想,⽽ Spring MVC 是对 MVC 思想的具体实现。
2. Spring、Spring Boot 与 Spring MVC
Spring MVC 与 Spring 同时产生,Spring MVC 是 Spring 的 Web 模块部分,也是 Spring 框架的核心部分,又叫 Spring Web MVC, Spring MVC 是基于 Servlet API 构建的。
而 Spring Boot 是后来产生的基于 Spring 为了更高效的使用 Spring 而开发出来的。
二. 创建 Spring MVC 项目
1. 创建项目
在创建 Spring Boot 项目时添加 Spring Web 依赖就是 Spring MVC 项目
2. 用户和程序的映射
创建⼀个 UserController 类,实现⽤户到 Spring 程序的互联互通
@Controller // 让 spring 框架启动时,把类加载进去
@ResponseBody // 返回⾮⻚⾯数据
@RequestMapping("/user") // 路由规则映射 一级路径
public class UserController {// 路由规则映射@RequestMapping("/hi") // 二级路径public String sayHi(){return "<h1>Hi,Spring MVC.</h1>";}
}
程序启动,访问地址:http://localhost:8080/user/hi 时就能打印“hello,spring mvc”的信息
@RequestMapping
⽤来注册接⼝的路由映射的。
路由映射指的是,当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类的某个⽅法的过程就叫路由映射。
- @RequestMapping 即可修饰类,也可以修饰⽅法,当修饰类和⽅法时,访问的地址是 类 + ⽅法 的路径 。
- @RequestMapping 也可以直接修饰⽅法,访问的地址直接就是⽅法上面的 路径。
- 注意 @RequestMapping 要搭配 @Controller 才能生效
@Controller // 让 spring 框架启动时,把类加载进去
@ResponseBody // 返回⾮⻚⾯数据
public class UserController {// 路由规则映射@RequestMapping("/hi") public String sayHi(){return "<h1>Hi,Spring MVC.</h1>";}
}
此时访问的路径是:http://localhost:8080/hi
默认 @RequestMapping 可以同时支持 GET 和 POST 请求,也可以进行设置。
@RequestMapping(method = RequestMethod.GET, value = "/hi") // 设置只支持 GET 请求
@RequestMapping(method = RequestMethod.POST, value = "/hi") // 设置只支持 POST 请求
也可以直接使用 @GetMapping 或者 @PostMapping
@GetMapping("/hi")
@PostMapping("/hi")
3. 获取用户请求参数
①. 获取单个参数
直接⽤⽅法中的参数来实现传参
@RequestMapping("/m1")public Object method_1(String name){System.out.println("参数 name:"+name);return name;}
注意:
- 前端传递的参数名称要与后端接收时使用的参数名一致
- 参数使用包装类,防止出现异常。比如整数使用 Integer.
②. 获取多个参数
与获取单个参数一样,参数写多个就行了,注意前后端名称一致, 前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置
是不影响后端获取参数的结果。
@RequestMapping("/m2")public Object method_2(String name, String password){System.out.println("参数 name:"+name+" password: "+ password);return "name: " + name + " passowrd:" + password;}
③. 传递对象
直接写对象即可,用户传递的参数的名称与对应的属性名一致。
⽐如 Person 对象:
@Data
public class Person {private int id;private String name;private String password;
}
@RequestMapping("/m3")public Object method_2(Person p){System.out.println("对象中的 name:"+p.getName());System.out.println("对象中的 password:"+p.getPassword());return "用户信息: " + p;}
当传递的参数与类的属性个数不一致时, 没有匹配上的属性取默认值.
④. 后端参数重命名(后端参数映射)@RequestParam
当前端传入的参数名称与后端参数不一致时, 可以使用 @RequestParam 来重命名前后端的参数值。
比如前端参数名为 time, 但是后端用 createtime, 后端就可以使用 @RequestParam 来重命名前后端的参数值.
也就是说使用 time 和 createtime 都能访问到 这个参数
@RequestMapping("/m4")public Object method_4(@RequestParam("time") String createtime) {System.out.println("时间:" + createtime);return "时间:" + createtime;}
注意: 假如我们使用 @RequestParam 了,那么如果前端不传递这个参数的话就会报错, 但是有时候这个参数不是必传参数, 此时我们就可以进行设置.
设置 @RequestParam 的一个属性 required = false 表示不传递这个参数也可以
@RequestParam(value = "time", required = false) String createtime
⑤. @RequestBody 接收JSON对象
@RequestMapping("/m5")public Object method_5(@RequestBody Person person) {System.out.println(person);return "响应信息: " + person;}
使用 POSTMAN 软件发送 JSON 格式的请求
假如把 @RequestBody 去掉
@RequestMapping("/m5")public Object method_5(Person person) {System.out.println(person);return "响应信息: " + person;}
后端根本就接收不到对应的信息
⑥. 获取URL中参数 @PathVariable
URL 中的参数, 并不是 URL 参数部分的参数
@RequestMapping("/m6/{name}/{password}")public Object method_6(@PathVariable String name, @PathVariable String password) {System.out.println("name:" + name);System.out.println("password:" + password);return "name:" + name + " password:" + password;}
注意: 这里面 @RequestMapping(“/m6/{name}/{password}”) 中的参数名称与下面方法中的参数名称也要保持一致
为什么在 URL 地址部分中要带参数, 写进参数部分中不是更好么?
- 因为在搜索结果中 参数写在地址部分中比写在参数部分中优先级更高.
1 属于 URL 地址, 一般不会改动, 2 中既有 URL 地址又有 URL 参数, 更容易发生改动, 所以 搜索结果中 1 排在更前面, 从而更容易让用户点击, 从而提高效益.
⑦. 上传文件 @RequestPart
@RequestMapping("/m7")public String method_7(@RequestPart("myfile") MultipartFile file) throws IOException {// 获取⽂件后缀名String fileName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));// ⽂件保存地址String filePath = ClassUtils.getDefaultClassLoader().getResource("static").getPath() +"/" + UUID.randomUUID() + fileName;// 保存⽂件file.transferTo(new File(filePath));return filePath + " 上传成功.";}
到对应文件存放的目录进行查找
注意 3 个要点:
- 存放的目录是什么? Linux 和 Windows 不一样, 要根据配置文件变化.
- 文件名称不能冲突, 所以可以使用 UUID (全球唯一 ID)防止覆盖(不使用时间戳因为高并发情况下很可能冲突)
- 文件格式不能变,所以需要获取文件的后缀
⑧. 获取Cookie
传统获取 cookie
Spring MVC 基于 Servlet 所以每个函数中都默认带有 HttpServletResponse、HttpServletRequest 这两个参数
@RequestMapping("/m8")@ResponseBodypublic String method_8(HttpServletResponse response, HttpServletRequest request) {// 获取所有 cookie 信息Cookie[] cookies = request.getCookies();// 遍历 cookies, 找到自己需要的 cookiefor (Cookie cookie: cookies) {if (cookie.getName().equals("username")) {// ...}}return "成功获取 cookie";}
简洁的获取 Cookie—@CookieValue, 直接获取自己想要的那个 cookie
@RequestMapping("/cookie")@ResponseBodypublic String cookie(@CookieValue("username") String username) {return "cookie:" + username;}
⑨. 获取 Session
Session 存储和 Servlet 类似,是使⽤ HttpServletRequest 中获取的
@RequestMapping("/setsess")@ResponseBodypublic String setsess(HttpServletRequest request) {// 获取 HttpSession 对象,参数设置为 true 表示如果没有 session 对象就创建⼀个sessionHttpSession session = request.getSession(true);if(session!=null){session.setAttribute("username","java");}return "session 存储成功";}
读取 Session 可以使⽤ HttpServletRequest
@RequestMapping("/sess")@ResponseBodypublic String sess(HttpServletRequest request) {// 参数为 false 如果 session 不存在,不会⾃动创建HttpSession session = request.getSession(false);String username = "暂⽆";if(session!=null && session.getAttribute("username")!=null){username = (String) session.getAttribute("username");}return "username:"+username;}
获取 Session 更简洁的⽅式:
@RequestMapping("/sess2")@ResponseBodypublic String sess2(@SessionAttribute(value = "username",required = false)String username) {return "username:"+username;}
⑩. 获取 header
传统获取 header
@RequestMapping("/m9")@ResponseBodypublic String method_9(HttpServletResponse response, HttpServletRequest request) {String userAgent = request.getHeader("User-Agent");return userAgent;}
简洁获取 Header—@RequestHeader
@RequestMapping("/header")@ResponseBodypublic String header(@RequestHeader("User-Agent") String userAgent) {return "userAgent:"+userAgent;}
4. 返回数据
① 返回静态页面
默认情况下返回的是视图(静态页面)(xxx.html)
创建前端⻚⾯ index.html
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>hello,spring mvc</title><script src="index.js"></script>
</head>
<body>
<h1>Hello,Spring MVC.</h1>
</body>
</html>
创建控制器 controller:
@Controller
@RequestMapping("/p")
public class PersonController {@RequestMapping("/index")public Object index(){// 执⾏业务...// 返回view -> index.htmlreturn "/index.html";}
}
②. 返回 text/html
想要返给给前端数据,这个时候我们就需要使⽤ @ResponseBody 注解
当返回数据是字符串是格式就是 text/html
@RequestMapping("/m")@ResponseBodypublic String method_7() {return "<h1>Hello,HTML~</h1>";}
③. 返回 JSON 对象
使用 @ResponseBody 注解后, 如果返回值是对象, 那么默认返回的就是 JSON 对象
@RequestMapping("/json")@ResponseBodypublic Object method_2() {Person person = new Person();person.setId(123);person.setName("zhouba");person.setPassword("999");return person;}
@ResponseBody 说明:
- @ResponseBody 返回的值如果是字符会转换成 text/html,如果返回的是对象会转换成 application/json 返回给前端。
- @ResponseBody 可以⽤来修饰⽅法或者是修饰类,修饰类表示类中的所有⽅法都会返回 html 或者 json,⽽不是视图。
- 组合注解:@RestController
@RestController = @Controller + @ResponseBody
④. 请求转发或请求重定向
return 不但可以返回⼀个视图,还可以实现跳转,跳转的⽅式有两种:
- forward 是请求转发;
- redirect:请求重定向。
举个栗子:
你告诉妈妈想吃辣条,如果妈妈说好,我帮你去买,这就是 forward 请求转发;如果妈妈让你⾃⼰去买,那么就是请求 redirect 重定向。
请求重定向:
// 请求重定向@RequestMapping("/index1")public String index1(){return "redirect:/index.html";}
浏览器中输入 http://localhost:8080/p/index1 会直接跳转到 http://localhost:8080/index.html
请求转发:
// 请求转发@RequestMapping("/index2")public String index2(){return "forward:/index.html";}
forward VS redirect :
- 请求重定向(redirect)将请求重新定位到资源,客户端重新请求;请求转发(forward)是服务器端转发。即请求重定向客户端两次请求, 而请求转发客户端只一次请求。
- 请求重定向地址发⽣变化,请求转发地址不发⽣变化。
- 请求重定向与直接访问新地址效果⼀直,不存在原来的外部资源不能访问;请求转发服务器端转发
有可能造成原外部资源不能访问。
请求转发如果资源和转发的⻚⾯不在⼀个⽬录下,会导致外部资源不可访问 (因为你只转发了一个页面,这个页面依赖的其他文件没有进行转发):
换为请求重定向:
好啦! 以上就是对 Spring MVC 程序开发 的讲解,希望能帮到你 !
评论区欢迎指正 !
相关文章:

【Spring】Spring MVC 程序开发
Spring MVC 程序开发 一. 什么是 Spring MVC1. MVC2. Spring、Spring Boot 与 Spring MVC 二. 创建 Spring MVC 项目1. 创建项目2. 用户和程序的映射3. 获取用户请求参数①. 获取单个参数②. 获取多个参数③. 传递对象④. 后端参数重命名(后端参数映射)R…...

如何在企业网站里做好网络安全
在当今数字时代,网站不仅仅是企业宣传和产品展示的平台,更是日常生活和商业活动中不可或缺的一部分。然而,随着网络技术不断发展,网站的安全问题日益凸显。保护网站和用户数据的安全已经成为至关重要的任务,以下是一些…...

windows server 2012 服务器打开系统远程功能
服务器上开启远程功能 进入服务器,选择“添加角色和功能” 需要选择安装的服务器类型,如图所示 然后在服务器池中选择你需要使用的服务器。 选择完成后,在图示列表下勾选“远程桌面服务” 再选择需要安装的功能和角色服务。 选择完成确认内容…...

智能工厂MES系统,终端设备支持手机、PDA、工业平板、PC
一、开源项目简介 源计划智能工厂MES系统(开源版) 功能包括销售管理,仓库管理,生产管理,质量管理,设备管理,条码追溯,财务管理,系统集成,移动端APP。 二、开源协议 使用GPL-3.0开…...

GPT的优势和GPT缺点
GPT,即Generative Pre-trained Transformer,是一种基于人工智能技术的自然语言处理模型。它采用了深度学习算法,可以通过大量的文本数据来学习自然语言的规律,并能够生成流畅、准确的语句。下面我们将探讨GPT技术的优势。 首先&a…...

微信小程序开发缺少中间证书问题(腾讯云、阿里云等做服务器)
项目使用nginx做负载均衡后,不再采用原来直接用jar包的方式直接开启对应端口,所以需要重新从云服务器上下载证书,写入到Nginx读取的证书路径上即可。...

动态代理初步了解
准备案例 需求 模拟某企业用户管理业务,需包含用户登录,用户删除,用户查询功能,并要统计每个功能的耗时。 分析与实现 定义一个UserService表示用户业务接口,规定必须完成用户登录,用户删除,…...

QT国际化
引入 在代码里面写中文就很low,运行时多语言切换是客户端程序都应该具备的。 qt国际化其实就是qt中字符串的字符集编码的设置。当然这个设置不是简单的选择一下什么语言就好,这个需要编程人员来处理的。 通常对于非拉丁字符(主要指latin1字符…...

微信小程序button按钮去除边框去除背景色
button边框 去除button边框 在button上添加plain“true”在css中添加button.avatar-wrapper {background: none}用于去除button背景色在css中添加button.avatar-wrapper[plain]{ border:0 }用于去除button边框...

Neo4j深度学习
Neo4j的简介 Neo4j是用Java实现的开源NoSQL图数据库。从2003年开始开发,2007年正式发布第一版,其源码托管于GitHtb。Neo4j作为图数据库中的代表产品,已经在众多的行业项目中进行了应用,如:网络管理、软件分析、组织和…...

【数据结构C/C++】链式存储与顺序存储结构栈
文章目录 链式存储结构顺序存储结构 下面这篇文章是我大二时候写的比较详细的实现过程,再这篇文章我也会再一次比较简单的再次简述一下链式与顺序存储结构的实现方式。 链式存储结构与顺序存储结构详解 这里我就不使用C再一次实现这两个栈了,有兴趣的也可…...

【数据库系统概论】数据定义之基本表的定义/创建、修改和删除
前言 🚩定义/创建基本表语法示例 修改基本表语法示例 删除基本表语法示例 感谢 💖 前言 🚩 SQL支持数据库系统的三级模式结构,其模式、外模式和内模式中的基本对象有表、视图和索引,因此,SQL的数据定义功能…...

面试算法22:链表中环的入口节点(1)
题目 如果一个链表中包含环,那么应该如何找出环的入口节点?从链表的头节点开始顺着next指针方向进入环的第1个节点为环的入口节点。 例如,在如图4.3所示的链表中,环的入口节点是节点3。 分析 第1步:确认是否包含环…...

蓝桥杯---第二讲---二分与前缀和
文章目录 前言Ⅰ. 数的范围0x00 算法思路0x00 代码书写 Ⅱ. 数的三次方根0x00 算法思路0x01代码书写 Ⅲ. 前缀和0x00 算法思路0x01 代码书写 Ⅳ. 子矩阵的和0x00 算法思路0x01 代码书写 Ⅴ. 机器人跳跃问题0x00 算法思路0x01 代码书写 Ⅵ. 四平方和0x00 算法思路0x01 代码书写 …...

d3dx9_39.dll如何修复?最新修复d3dx9_39.dll方法分享
大家好!今天我要和大家分享的主题是“d3dx9_39.dll丢失的修复方法”。我们都知道,在使用电脑的过程中,经常会遇到各种问题,而其中最常见的就是文件丢失。d3dx9_39.dll就是其中一个常见的丢失文件。那么,如何修复这个丢…...

阿里云轻量应用服务器月流量限制说明(部分套餐不限流量)
阿里云轻量应用服务器部分套餐限制月流量,轻量应用服务器按照套餐售卖,有的套餐限制月流量,有的不限制流量。像阿里云轻量2核2G3M带宽轻量服务器一年108元和轻量2核4G4M带宽一年297.98元12个月,这两款是不限制月流量的。阿里云百科…...

项目设计:YOLOv5目标检测+机构光相机(intel d455和d435i)测距
1.介绍 1.1 Intel D455 Intel D455 是一款基于结构光(Structured Light)技术的深度相机。 与ToF相机不同,结构光相机使用另一种方法来获取物体的深度信息。它通过投射可视光谱中的红外结构光图案,然后从被拍摄物体表面反射回来…...

WPF中DataContext的绑定技巧
先看效果: 上面的绑定值都是我们自定义的属性,有了以上的提示,那么我们可以轻松绑定字段,再也不用担心错误了。附带源码。 目录 1.建立mvvm项目 2.cs后台使用DataContext绑定 3.xaml前台使用DataContext绑定 4.xaml前台使用Da…...

【Spring MVC研究】MVC原理:DispatcherServlet的初始化,初始化好等于MVC准备好
文章目录 1. EnableWebMVC 开启 MVC 功能2. 初始化自定义的 MVC 组件2.1. 初始化过程2.2. 如何分析复杂的 Spring 组件注册 3. 容器启动后会初始化 DispatcherServlet4. DispatcherServlet 初始化过程总结5. 资料参考 把DispatcherServlet 准备好意味着服务器已经可以处理请求了…...

Kafka的分布式架构与高可用性
导语 一开始我们就说过Kafka是一款开源的高吞吐、分布式的消息队列系统,那么今天我们就来说下它的分布式架构和高可用性以及双/多中心部署。 Kafka 体系架构简介 以下是 Kafka 的软件架构,整个 Kafka 体系结构由 Producer、Consumer、Broker、ZooKeepe…...

Spring Cloud学习笔记【分布式请求链路跟踪-Sleuth】
文章目录 Spring Cloud Sleuth概述概述主要功能:Sleuth中的术语和相关概念官网 zipkin配置下载运行zipkin下载zipkin运行 demo配置服务提供者 lf-userpom.xmlapplication.ymlUserController 服务调用者 lf-authpom.xmlapplication.ymlAuthController 测试 Spring Cl…...

Java开发中的操作日志详解(InsCode AI 创作助手)
Java开发中的操作日志详解 一、操作日志的作用 故障排除和调试: 操作日志可以记录应用程序的各种活动,包括错误、异常、警告和信息性消息。这有助于开发人员快速定位和解决问题。性能分析: 通过记录关键操作和性能指标,操作日志…...

FutureTask和CompletableFuture的模拟使用
模拟了查询耗时操作,并使用FutureTask和CompletableFuture分别获取计算结果,统计执行时长 package org.alllearn.futurtask;import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; imp…...

Redis作为缓存,mysql的数据如何与redis进行同步?
Redis作为缓存,mysql的数据如何与redis进行同步? 一定要设置前提,先介绍业务背景 延时双删 双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致 读操作:缓存命中,直接返回;缓存未…...

申请免费 SSL 证书为您的小程序加密通信
在今天的网络环境中,数据安全和隐私保护变得尤为重要。无论是网站还是应用程序,为其提供安全的通信渠道都是至关重要的。对于小程序开发者来说,使用 SSL(Secure Sockets Layer)证书可以有效地保障用户数据的安全&#…...

Go 并发编程
并发编程 1.1 并发与并⾏ 并⾏与并发是两个不同的概念,普通解释: 并发:交替做不同事情的能⼒并⾏:同时做不同事情的能⼒ 如果站在程序员的⻆度去解释是这样的: 并发:不同的代码块交替执⾏并⾏…...

鱼眼相机去畸变(图像拉直/展开/矫正)算法及实战总结
本文介绍两种方法 1、经纬度矫正法 2、棋盘格矫正法 一、经纬度矫正法 1、算法说明 经纬度矫正法, 可以把鱼眼图想象成半个地球, 然后将地球展开成地图,经纬度矫正法主要是利用几何原理, 对图像进行展开矫正。 经过P点的入射光线…...

es6 数据类型
es6 数据类型 map 数据类型 >Map 对象保存键值对。 用途 : Object的key无法支持该数据时需要了解对象大小时 map 数据类型任何值(对象或者原始值) 都可以作为一个键。 Object 的键只能是字符串 let myMap new Map(); let myMap1 new Map(); var keyStrin…...

【postgresql】
看到group by 1,2 和 order by 1, 2。看不懂,google,搜到了Stack Overflow 上有回答 What does SQL clause “GROUP BY 1” mean? 大概意思就是,group by, order by 后面跟数字,指的是 selec…...

【C++】空间配置器 allocator:原理及底层解析
文章目录 空间配置器一级空间配置器二级空间配置器1. 内存池2. SGI-STL中二级空间配置器设计 - - 哈希桶3. 二级空间配置器的空间申请 空间配置器的默认选择空间配置器的在封装:添加了数据类型大小空间配置器对象的构造与析构 容器中的 allocator 空间配置器 提到空…...