SpringMVC 程序开发

news2024/11/29 0:39:27

✏️作者:银河罐头
📋系列专栏:JavaEE

🌲“种一棵树最好的时间是十年前,其次是现在”

目录

  • 什么是 Spring MVC
    • MVC 定义
  • 怎么学 Spring MVC
    • Spring MVC 创建和连接
      • 创建 Spring MVC 项目
      • @RequestMapping 注解介绍
      • @PostMapping
    • 获取参数
      • 获取单个参数
      • 获取多个参数
      • 传递对象
      • 后端参数重命名
      • @RequestBody 接收JSON对象
      • 获取URL中参数@PathVariable
      • 上传文件@RequestPart
      • 获取Cookie/Session/header
    • 返回数据

什么是 Spring MVC

SSM = Spring Boot + Spring Web(Spring MVC) + MyBatis

Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。它的正式名称"Spring Web MVC"来自其源模块的名称(Spring-webmvc), 但它通常被称为"Spring MVC".

  1. Spring MVC 是⼀个 Web 框架。
  2. Spring MVC 是基于 Servlet API 构建的。

MVC 定义

MVC 是 Model View Controller 的缩写,它是软件⼯程中的⼀种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分。

image-20230524210331588

怎么学 Spring MVC

学习 Spring MVC 我们只需要掌握以下 3 个功能:

1.连接的功能:将⽤户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调⽤到我们的 Spring 程序

2.获取参数的功能:⽤户访问的时候会带⼀些参数,在程序中要想办法获取到参数。

3.输出数据的功能:执⾏了业务逻辑之后,要把程序执⾏的结果返回给⽤户。

对于 Spring MVC 来说,掌握了以上 3 个功能就相当于掌握了 Spring MVC。

Spring MVC 创建和连接

创建 Spring MVC 项目

2018年之前,使用 maven 项目添加 Spring MVC 框架的方式来创建,太复杂。

2018年之后 ,使用 Spring Boot 来创建 Spring MVC 项目。

@RestController
public class UserController {

    @RequestMapping("/say")//可以是 1 级路由,也可以是 n 级路由
    public String sayHi(){
        return "hi spring mvc";
    }
}

image-20230525093524841

实现用户到 spring 程序的连接。

@RequestMapping 注解介绍

它支持 GET 请求

image-20230525094012167

那它是否支持 post 请求?

用 postman 测试:

image-20230525094308605

得出结论:它也支持 POST 请求.

image-20230525094720999

GET, HEAD, POST,PUT, PATCH, DELETE, OPTIONS, TRACE 都支持。

在浏览器地址栏输入地址,默认是 GET 请求。

  • 如果我想设置成只支持其中某一种请求类型,如何实现?
@RestController
public class UserController {
    @RequestMapping(value = "/sayhi",method = RequestMethod.POST)
    public String sayHi(){
        return "hi spring mvc";
    }
}

image-20230525095737251

设置成只支持 POST 请求,再发 GET 请求就失败了。

@PostMapping

除了通过 @RequestMapping 来设置 POST,还可以通过@PostMapping 来设置。

@PostMapping("/sayhello")
public String sayHello(){
    return "hello spring mvc";
}

image-20230525101343151

小结:

2种实现路由连接的方式 :@RequestMapping 和 @PostMapping

@GetMapping("/hi")
public String hi(){
    return "spring mvc hi";
}

获取参数

获取单个参数

@RequestMapping("/sayhi")
public String sayHi(String name){
    return "hi " + name;
}

image-20230525104224079

这里地址栏里 key 必须写"name", 才能成功拿到 value

image-20230525104425955

image-20230525104553806

如果传了错误的 key 或者不传参数 ,结果就是String 的默认值 null

@RequestMapping("/sayhi2")
public String sayHi2(Integer id){
    return "hi " + id;
}

image-20230525104909702

@RequestMapping("/sayhi3")
public String sayHi3(int id){
    return "hi " + id;
}

image-20230525104950110

参数传递不要使用基本数据类型(如 int)。

@RequestMapping("/sayhi4")
public String sayHi4(HttpServletRequest request, HttpServletResponse response){
    return "hi " + request.getParameter("name");
}

image-20230525105923750

@RequestMapping("/sayhi4")
public String sayHi4(HttpServletRequest request, HttpServletResponse response) throws IOException {
    response.sendRedirect("https://www.sogou.com");
}

还可以实现重定向跳转页面。

获取多个参数

@RequestMapping("/sayhi")
public String sayHi(String name, String password){
    return "name =  " + name + "  | password = " + password;
}

image-20230525120905027

参数顺序不重要,保证 key 正确就行。

传递对象

@Data
public class Userinfo {
    private int id;
    private String name;
    private String password;
    private int age;
}
//获取对象
@RequestMapping("/reg")
public Object reg(Userinfo userinfo){
    return userinfo;
}

image-20230525121910432

@RequestMapping("/h1")
public Object getH1(){
    return "<h1>我是 h1</h1>";
}

image-20230525122546245

后端参数重命名

某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不⼀致, 比如前端传递一个 username 给后端,后端用 name 接收,这样就会出现参数接收不到的情况,如果出现这种情况,我们就可以使用@RequestParam 来重命名前后端的参数值。

@RequestMapping("/reg2")
public Object reg(@RequestParam("username") String name, String password){
    return "name = " + name + "  | password = " + password;
}

image-20230525123606776

如果前端传的是 name, 会怎样?

image-20230525124506164

image-20230525124602939

规定 前端必须传 “username”.

@RequestMapping("/reg2")
public Object reg(@RequestParam(value = "username",required = false) String name, 
                  String password){
    return "name = " + name + "  | password = " + password;
}

required = false 设置之后

image-20230525124843490

前端:对象/JSON 对象字符串

后端:对象/JSON 对象字符串

@RequestBody 接收JSON对象

用之前接收对象的方式,不能成功接收到 JSON 对象。

@RequestMapping("/reg")
public Object reg(Userinfo userinfo){
    System.out.println(userinfo);
    return userinfo;
}

用 postman 发送一个 post 请求。

image-20230526161624662

用 @RequestBody 这个注解就可以成功接收到 JSON 对象了。

@RequestMapping("/reg3")
public Object reg3(@RequestBody Userinfo userinfo){
    return userinfo;
}

image-20230526162053237

获取URL中参数@PathVariable

/user?uid=12345

/user/12345 优点:搜索引擎抓取关键字权重更高,更简洁

@RequestMapping("/reg4/{name}/{password}")
public Object reg4(@PathVariable String name, @PathVariable String password){
    return "name = " + name + " | password = " + password;
}

image-20230526173548560

如果把路径里的 password 改成 pwd,会怎样?

image-20230526173830789

image-20230526173849026

image-20230526173933382

这个参数是必须的。所以会报错。

@RequestMapping("/reg4/{name}/{pwd}")
public Object reg4(@PathVariable String name, @PathVariable(required = false) String password){
    return "name = " + name + " | password = " + password;
}

image-20230526174116844

加 required = false 之后就不会报错,但是 还是得不到 password 的值。

小结:

@PathVariable: 基础 url 里面的参数(? 之前的参数)

@RequestParam: url 参数部分的参数(? 之后的参数)

@RequestMapping("/reg4/{name}/{pwd}")
public Object reg4(@PathVariable String name, @PathVariable(required = false,name = "pwd") String password){
    return "name = " + name + " | password = " + password;
}

image-20230526175020377

上传文件@RequestPart

@RequestMapping("/myupload")
public Object upload(@RequestPart("myimg")MultipartFile file){
    File saveFile = new File("D:\\Data\\myimg.png");
    try {
        file.transferTo(saveFile);
        return true;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}

用 postman 发送 post 请求:

image-20230526185447372

image-20230526185519850

文件上传成功。

默认要求上传单个文件大小不超过 1MB.

Common Application Properties (spring.io)

image-20230526191038458

如果我要上传的文件很大怎么办?

image-20230526192305252

可以设置上传文件大小。

有一个问题,后面上传的文件会把之前的文件覆盖。

MySQL -> InnoDB(5.5) -> B+存储 -> 聚簇索引树

叶子(数据页) 主键(如果有) + 数据

  • 如何保证每次上传的文件不会覆盖?也就是最终保存的是不同的文件名。

UUID。

image-20230526194438761

//上传文件
@RequestMapping("/myupload")
public Object upload(@RequestPart("myimg")MultipartFile file){
    String fileName = UUID.randomUUID() + //文件名
            file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));//后缀名
    File saveFile = new File("D:\\Data\\" + fileName);
    try {
        file.transferTo(saveFile);
        return true;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}

image-20230526195229489

成功上传,没有覆盖原有的。

获取Cookie/Session/header

//获取 cookie
@RequestMapping("/getCookie")
public Object getCookie(@CookieValue(value = "java",required = false) String java){
    return "java = " + java;
}

image-20230526203510999

我们可以手动构造一个 cookie。

image-20230526203720519

  • 获取 Header
//获取 header
@RequestMapping("/header")
public Object getHeader(@RequestHeader("user-agent") String userAgent){
    return "userAgent = " + userAgent;
}

image-20230526204630024

  • 获取 Session
private static final String SESSION_KEY = "USERINFO_SESSION_KEY";
//存储 session
@RequestMapping("/setSession")
public void setSession(HttpServletRequest request){
    HttpSession session = request.getSession();//没有就创建,默认是 true
    session.setAttribute(SESSION_KEY,"zhangsan");
}
//获取 session
@RequestMapping("/session")
public Object getSession(@SessionAttribute(SESSION_KEY) String name){
    return "session = " + name;
}

image-20230526211355550

返回数据

1)返回静态页面

@Controller
@RequestMapping("/test")
public class TestController {

    @RequestMapping("/getIndex")
    public Object getIndex(){
        return "index.html";
    }
}

image-20230526212609378

image-20230526212624263

确认 target 下有 index.html.

那是什么原因?

image-20230527152437083

加了"/"之后就能访问成功了。

image-20230527152527859

加了"/“表示是 从根目录去找"index.html”, 不加"/"是在 test 目录下去找 "index.html"就找不到.

image-20230527152858995

image-20230527153309749

2)请求转发或请求重定向

1.请求转发

//请求转发
@RequestMapping("/forward")
public String forward(){
    return "forward:/index.html";
    //return "/index.html"; 默认就是请求转发
}

image-20230527163136991

2.请求重定向

//请求重定向
@RequestMapping("/redirect")
public String redirect(){
    return "redirect:/index.html";
}

image-20230527163210272

@RequestMapping("/redirect2")
public void redirect2(HttpServletResponse response) throws IOException {
    response.sendRedirect("https://www.baidu.com");
}

forward 和 redirect 具体区别如下:

  1. 请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务器端转发。
  2. 请求重定向地址发生变化,请求转发地址不发⽣变化。
  3. 请求重定向,不存在原来的外部资源不能访问;请求转发服务器端转发 有可能造成原外部资源不能访问。

举例:

请求转发:张三找李四借钱,李四自己也没钱,李四又去找王五借,最终张三只借了一次钱,剩下的事都是 李四干的。

请求重定向:张三找李四借钱,李四自己也没钱,李四告诉张三说自己没钱让张三去找王五借钱。然后张三又去找王五借到了钱。

请求转发和请求重定向有什么区别? | Javaᶜⁿ 面试突击 (javacn.site)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/576599.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二叉搜索树的实现(C语言)

目录 前言&#xff1a; 一&#xff1a;准备工作 (1)需要的头文件 (2)树节点结构体描述 (3)初始化 二&#xff1a;指针 三&#xff1a;插入新节点(建树) (1)生成一个新节点 (2)找插入位置 四&#xff1a;查找和遍历 (1)查找 (2)遍历 五&#xff1a;删除节点 六&…

mysql 主从同步

① 修改 master 配置文件② 新建同步账号③ 创建数据库④ 修改 slave 配置文件⑤ 配置主从关系⑥ 检验主从结果 角色ipmaster192.168.233.100slave1192.168.233.101slave2192.168.233.102 禁用 selinux 跟 firewal l情况下&#xff1a; ① 修改 master 配置文件 vim /etc/my…

NEFU linux实验二

在linux中&#xff0c;家目录又称“home目录”、“主目录”&#xff0c;是用户的宿主目录&#xff0c;通常用来保存用户的文件&#xff0c;可以使用“~”来表示。一个用户登录系统&#xff0c;进入后所处的位置就是“/home”&#xff0c;即家目录&#xff1b;root用户的家目录为…

路径规划算法:基于鸡群优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于鸡群优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于鸡群优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法鸡群…

输电线路故障诊断(利用随机森林方法实现二分类和多分类)

1.simunlike仿真系统的建立&#xff08; 运行效果 &#xff1a;输电线路故障诊断_哔哩哔哩_bilibili&#xff09; 2.在仿真系统的基础上获取数据集 分别获取单相接地故障、两相接地故障、两相间短路故障、三相接地故障、三相间短路故障和正常状态下的电流&#xff08;Ia,Ib,I…

一文带你了解MySQL之optimizer trace神器的功效

前言&#xff1a; 对于MySQL 5.6以及之前的版本来说&#xff0c;查询优化器就像是一个黑盒子一样&#xff0c;你只能通过EXPLAIN语句查看到最后优化器决定使用的执行计划&#xff0c;却无法知道它为什么做这个决策。这对于一部分喜欢刨根问底的小伙伴来说简直是灾难&#xff1…

2023年5月14日蓝桥杯c++省赛中级组

选择题讲解 1.)C++中,bool类型的变量占用字节数为 ( )。 A.1B.2 C.3 D.4 答案:A 解析:(C++ 中 bool 类型与 char 类型一样,都需要1 byte。一些其他类型的占用字节数:short:2 byte。int:4 byte。long long:8 byte。double:8 byte。) 2.)以下关于C++结构体的说…

代码随想录二刷 day04 | 链表之 24两两交换链表中的节点 19删除链表的倒数第N个节点 面试题 02.07. 链表相交 142.环形链表II

24. 两两交换链表中的节点 题目链接 解题思路&#xff1a; 先将一些可能会改变的节点保存一下&#xff0c;然后再按照三个步骤就行修改 注意 要使用改变以后节点的指针&#xff08;这个地方一刷的时候没注意到&#xff0c;稀里糊涂的过去了&#xff09; 代码如下&#xff1a;…

【八股】计算机网络-HTTP和HTTPS的区别、HTTPS加密传输原理

计算机网络-HTTP和HTTPS的区别、HTTPS加密传输原理 一、HTTP和HTTPS的基本概念二、HTTP与HTTPS的区别三、HTTPS加密传输原理1. 什么是HTTPS1.1 https诞生的原因1.2 https加密方式1.3.http和https的区别 2. https的工作流程3. 数字证书3.1 什么是数字证书3.2 如何申请数字证书3.…

亚马逊六页纸沟通法,拒绝PPT

亚马逊六页纸沟通管理法&#xff0c;拒绝PPT 使用一种简洁的「结构化备忘录」 内部管理会议沟通&#xff0c;每次不超过六页 趣讲大白话&#xff1a;让沟通更有效 【趣讲信息科技178期】 **************************** 那么“6页备忘录”到底是什么呢&#xff1f; 1. What we d…

供应链 | 在线平台的研究与思考(一):销售渠道与模式选择

封面图来源&#xff1a; https://www.pexels.com/zh-cn/photo/4968391/ 编者按 当前&#xff0c;电商平台主要采用两种销售模式&#xff1a;代理和分销。商家根据自身情况选择线上或线下渠道&#xff0c;而电商平台会根据不同的线上商家选择适当的分销模式。本期编者精选的两…

Unity 工具 之 Azure 微软语音合成普通方式和流式获取音频数据的简单整理

Unity 工具 之 Azure 微软语音合成普通方式和流式获取音频数据的简单整理 目录 Unity 工具 之 Azure 微软语音合成普通方式和流式获取音频数据的简单整理 一、简单介绍 二、实现原理 三、注意实现 四、实现步骤 六、关键脚本 一、简单介绍 Unity 工具类&#xff0c;自己整…

从事黑客工作十余年,究竟如何成为一名高级的安全工程师?

目录 1. 前言 2. 经验 3. 要考虑的问题 4. 学习路线详解 第一步&#xff1a;计算机基础 第二步&#xff1a;编程能力 第三步&#xff1a;安全初体验 第四步&#xff1a;分方向 尾言 参考书籍列表 1. 前言 说实话&#xff0c;一直到现在&#xff0c;我都认为绝大多数…

STP协议

目录 STP的基本概念&#xff1a; 桥ID&#xff08;Bridge ID&#xff09;&#xff1a; 根桥&#xff1a; 开销&#xff08;Cost&#xff09;&#xff1a; RPC&#xff08;根路径开销&#xff09;&#xff1a; Port ID&#xff1a; BPDU&#xff1a;&#xff08;网桥协议…

ROS:ROS是什么

目录 一、ROS简介二、ROS可以做些什么三、ROS特征四、ROS特点4.1点对点设计4.2不依赖编程语言4.3精简与集成4.4便于测试4.5开源4.6强大的库与社区 五、ROS的发展六、ROS架构6.1OS层6.2中间层6.3应用层 七、通信机制八、计算图8.1节点&#xff08;Node&#xff09;8.2节点管理器…

当ChatGPT参加中国高考,把全国A卷B卷喂给它后,竟严重偏科

作者 |Python ChatGPT作为一个智能人机对话应用&#xff0c;在推出后迅速风靡全球。仅仅一个月的时间&#xff0c;其用户数量已经突破了一亿大关。人们也用ChatGPT测试了很多考试项目&#xff0c;例如SAT、AP、GRE等。然而&#xff0c;如果让ChatGPT来参加我们中国的高考&…

Jetson Orin Nano 快速安装 ROS2 Foxy详解

大家好&#xff0c;我是虎哥&#xff0c;入手一块Jeston Orin nano 8G模块&#xff0c;这个模块因为是英伟达未来5年左右主推的模块&#xff0c;所以我逐步会将之前所有的应用都在这个模块环境上做适配&#xff0c;本章内容&#xff0c;我将主要围绕安装ROS2 Foxy版本为主展开。…

探索Java面向对象编程的奇妙世界(四)

⭐ 变量的分类和作用域⭐ 包机制(package、import)⭐ 面向对象三大特征——继承⭐ 继承的作用⭐ 继承的实现⭐ instanceof 运算符⭐ 继承使用要点⭐ 方法重写 override⭐ final 关键字⭐ 继承和组合 ⭐ 变量的分类和作用域 变量有三种类型&#xff1a;局部变量、成员变量(也称为…

Diffusion Model 深入剖析

Diffusion Model 深入剖析 最近AI生成艺术领域非常火热&#xff0c;从 Midjourney 到 Stable Diffusion&#xff0c;不管你是绘画高手还是艺术小白&#xff0c;只要输入想要绘制内容的描述或者基础图像&#xff0c;就可以生成富有艺术感的画作&#xff01; 这些风格各异、以假…

CodeForces..构建美丽数组.[简单].[情况判断].[特殊条件下的最小值奇偶问题]

题目描述&#xff1a; 题目解读&#xff1a; 给定数组a[n]&#xff0c;ai>0&#xff0c;问能否得到一个数组b[n]&#xff0c;数组b中的元素都大于0且全奇or全偶。 数组b中的元素biai or ai-aj&#xff08;1<j<n&#xff09;。 解题思路&#xff1a; 数组b中的元素都…