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

【Spring MVC】

目录

🍮1 什么是 MVC ?

🎁2 Spring MVC 的连接

🍘2.1 @RequestMapping 实现 POST 和 GET 请求

🥣2.2 @GetMapping 只支持 GET 请求

🫖2.3 @PostMapping 只支持 POST 请求

🍬3 Spring MVC 获取参数的功能

🍩3.1 传递单个参数

😚3.2 传递对象

🍟3.3 后端参数重命名

🍭3.4 获取 json 对象

🧃3.5 获取 URL 中参数 @PathVariable

🍳3.6 上传文件 @RequestPart

😎3.7 获取 cookie

🍉3.8 获取 session

🍖3.9 获取 header

🍱4 Spring MVC 输出数据的功能

🎑 5. 请求转发与请求重定向的区别


1 什么是 MVC ?

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

 MVC 的作用是将软件用户界面与业务逻辑分离,从而使代码变得更加容易维护、更加易于复用,灵活性更强。总的来说就是,View 层是界面,Model 层是业务逻辑,Controller 层用来调度 View 层以及 Model 层,是用户界面与业务逻辑沟通的桥梁。

实现逻辑是这样子的:View 提交数据给 Model,让它实现某一具体逻辑,但在 MVC 中,View 不会直接就交给 Model,而是交给了 Contrller,让 Contrller 转交给 Model。乍一看,还觉得复杂了。但如果有一天,旧的业务逻辑不再适用了呢,此时只需要在 Controller 中将原来的 Model 替换成新的 Model 就可以,旧的依旧可以保留。Controller 起到中转站的作用,将不同的 View 转到对应的 Model 中。

MVC 是一种思想,而 Spring MVC 是对 MVC 的具体实现,是一个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架。

市面上绝大多数的 Java 项目是基于 Spring 或 Spring Boot 的,而 Spring MVC 就是 Spring 的核心框架,可以说 Spring MVC 是一切项目的基础,这也是我们学习 Spring MVC 的一个重要原因。

2 Spring MVC 的连接

路由映射:当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类或某个类的某个⽅法的过程。

2.1 @RequestMapping 实现 POST 和 GET 请求

package com.example.demo.Controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class TestController {@RequestMapping("/sayhi")public String sayHi(){return "你好 Spring MVC";}
}

@RequestMapping 是 Spring Web 中最常⽤到的注解之⼀,它是⽤来注册接⼝的路由映射的。

@RequestMapping 即可修饰类,也可以修饰⽅法,当修饰类和⽅法时,访问的地址是类 + ⽅ 法。 @RequestMapping 也可以直接修饰⽅法,此时直接写方法地址即可。

 

 

如果想要规定 @RequestMapping 只支持 Post 请求,那么就得加参数了。

package com.example.demo.Controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class TestController {@RequestMapping(path = "/sayhi", method = RequestMethod.POST)public String sayHi(){return "你好 Spring MVC";}
}

 

 由于浏览器的默认方法是 GET 请求,所以浏览器也请求失败了。

 

package com.example.demo.Controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class TestController {@RequestMapping(path = "/sayhi", method = RequestMethod.GET)public String sayHi(){return "你好 Spring MVC";}
}

 

2.2 @GetMapping 只支持 GET 请求

@GetMapping("/sayhi2")public String sayHi2(){return "Hey You!";}

 等价于上面的 @RequestMapping(path = "/sayhi", method = RequestMethod.GET)

2.3 @PostMapping 只支持 POST 请求

@PostMapping("/sayhi3")public String sayHi3(){return "Yo Ho~~ Beauty~";}

等价于上面的 @RequestMapping(path = "/sayhi", method = RequestMethod.POST)

3 Spring MVC 获取参数的功能

3.1 传递单个参数

package com.example.demo.Controller;import com.example.demo.Model.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test2")
public class TestController2 {// 传递单个参数@RequestMapping("/single")public String wordOfFamily(String word){return word;}
}

3.2 传递对象

package com.example.demo.Model;import lombok.Data;@Data
public class User {private int id;private String name;private String password;private int age;
}

package com.example.demo.Controller;import com.example.demo.Model.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test2")
public class TestController2 {// 传递对象@RequestMapping("/user")public User userMessage(User user){return user;}
}

 

也可以使用 form 表单提交。

 

3.3 后端参数重命名

某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不⼀致,⽐如前端传递了⼀个 time 给后端,⽽后端⼜是有 createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,我们就可以使⽤ @RequestParam 来重命名前后端的参数值。

    // 后端参数重命名@RequestMapping("/name")public String name(@RequestParam(value = "time") String createtime ){return createtime;}

上⾯的列⼦,如果我们是前端传递⼀个⾮ time 的参数,就会出现程序报错的情况。这是因为后端已经声明了前端必须传递⼀个 time 的参数,但是前端没有给后端传递,我们查看 @RequestParam 注解的实现细节就可以发现端倪,注解实现如下:

required 必须的意思,默认值为 true,前端一定要传递指定参数,否则就会 400 报错。

如果我们的实际业务前端的参数是⼀个⾮必传的参数,我们可以通过设置 @RequestParam 中的 required=false 来避免不传递时报错,具体实现如下:

    // 后端参数重命名@RequestMapping("/name")public String name(@RequestParam(value = "time", required = false) String createtime ){return createtime;}

 

3.4 获取 json 对象

使用 RequestBody 来获取 json 对象,只能用来修饰参数。

    // 接收 json 格式@RequestMapping("/user_json")public User userJson(@RequestBody User user){return user;}

 

看过上面的那么多例子,会发现框架会根据输入的参数类型,返回相应的格式。如果是 html 呢?

    @RequestMapping("/html")public String html(){return "<h1>hello html<h1>";}

 

 

3.5 获取 URL 中参数 @PathVariable

之前是通过 URL 参数部分去获取参数的,这一部分讲解从 URL 地址部分/非参数部分获取参数。比如下面的稀土掘金:

 最后的那串数字是文章的 id,但不是使用以前的那种写法 ?id=7269952188927017015

    // URL非参数部分获取参数@RequestMapping("/detail/{id}")public Integer detail(@PathVariable("id") Integer id){return id;}

// URL 获取多个参数@RequestMapping("/detail2/{id}/{name}")public String detail2(@PathVariable Integer id, @PathVariable String name){return "id = "+id+" name = "+name;}

3.6 上传文件 @RequestPart

上传文件使用 POST 请求。

    // 上传文件@RequestMapping("upload")public String upload(@RequestPart("myfile")MultipartFile file) throws IOException {String path = "C:\\image\\img.png";//保存文件file.transferTo(new File(path));return path;}

 所有上传的图片都会被命名成 img.png ,可不可以更加灵活的处理保存上传图片并命名呢?

生成唯一的 id,一定使用 UUID。觉得 UUID 中的 - 很难看,可以去掉。UUID 是全球唯一 id。

UUID = 网卡+随机数+随机种子+加密算法

保证其唯一性

// 上传文件修改版本@RequestMapping("upload")public String upload1(@RequestPart("myfile")MultipartFile file) throws IOException {// 1. 生成一个唯一的 id | UUID String name = UUID.randomUUID().toString().replace("-","");// 2. 得到源文件的后缀名// 对完整文件名进行截取name += (file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")));String path = "C:\\image" + name ;//保存文件file.transferTo(new File(path));return path;}

3.7 获取 cookie

// 获取 Cookie@RequestMapping("/getcookie")public String cookie(@CookieValue(value = "java", required = false) String ck){return ck;}

3.8 获取 session

    // 设置 Session@RequestMapping("/set_session")public String setSession(HttpServletRequest request){HttpSession session = request.getSession();if(session != null){session.setAttribute("SESSION_KEY", "栗子");return "session set successes";}else{return "session set fails";}}/*** 获取 Session*/@RequestMapping("/get_session")public String getSession(@SessionAttribute(required = false, value = "SESSION_KEY") String name){return name;}

 

3.9 获取 header

    // 获取 header@RequestMapping("/header")public String header(@RequestHeader("User-Agent") String userAgent){return userAgent;}

4 Spring MVC 输出数据的功能

package com.example.demo.Controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class TestController3 {@RequestMapping("/index")public String index(){return "hello.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>Document</title>
</head>
<body>
<h1>hello, I'm a hello page~~</h1>
</body>
</html>

 早期的 Spring MVC 前端不分离,后端会给前端返回一个 html 的网页,如今前后端分离了,后端只负责给前端传递数据,这就用到了 @ResponseBody 这个注解。

package com.example.demo.Controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
@ResponseBody
public class TestController3 {@RequestMapping("/index")public String index(){return "hello.html";}
}

 5. 请求转发与请求重定向的区别


相关文章:

【Spring MVC】

目录 &#x1f36e;1 什么是 MVC &#xff1f; &#x1f381;2 Spring MVC 的连接 &#x1f358;2.1 RequestMapping 实现 POST 和 GET 请求 &#x1f963;2.2 GetMapping 只支持 GET 请求 &#x1fad6;2.3 PostMapping 只支持 POST 请求 &#x1f36c;3 Spring MVC 获取参数的…...

【ES】笔记-生成器函数与调用

function* function* 这种声明方式 (function关键字后跟一个星号&#xff09;会定义一个生成器函数 (generator function)&#xff0c;它返回一个 Generator 对象。 function * gen(){console.log("heloo generator")}如何调用呢&#xff1f;先看下里面的内容 返回…...

将Spring Boot与Redis集成

一、引言 1、SpringBoot&#xff1a; Spring Boot是一个用于创建独立且可执行的Spring应用程序的框架。它简化了基于Spring框架的应用程序的开发过程&#xff0c;并提供了一种快速和简便的方式来构建Java应用程序。 Spring Boot提供了自动配置机制&#xff0c;通过引入适当的…...

vue echarts

安装 npm i -D echarts使用 <script setup lang"ts"> import * as echarts from echarts import { onMounted } from vueonMounted(() > {interface DataItem {value: [string, number]}let myChart echarts.init(document.getElementById(main))let dat…...

idea上利用JDBC连接MySQL数据库(8.1.0版)

1.了解jdbc概念 JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API&#xff0c;可以为多种 关系数据库提供统一访问&#xff0c;它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准&#xff0c;据此可以构建 更高级的工具和接口&#…...

【100天精通python】Day47:python网络编程_Web编程基础

目录 1 网络编程与web编程 1.1 网络编程 1.2 web编程 2 Web开发概述 3 Web开发基础 3.1 HTTP协议 3.2 Web服务器 3.3 前端基础 3.4 静态服务器 3.5 前后端交互的基本原理 4 WSGI接口 4.1 CGI 简介 4.2 WSGI 简介 4.3 定义 WSGI 接口 4.4 运行 WSGI 服务 4.5…...

DockerCompose介绍与使用

DockerCompose介绍与使用 1、DockerCompose介绍 DockerCompose用于定义和运行多容器 Docker 应用程序的工具。 通过 Compose可以使用 YAML 文件来配置应用程序需要的所有服务。一个使用Docker容器的应用&#xff0c;通常由多个容器组成&#xff0c;使用Docker Compose不再需要…...

Windows Qt 5.12.10下载与安装

Qt 入门实战教程&#xff08;目录&#xff09; C自学精简实践教程 目录(必读) 1 Qt5.12.10下载 qt-opensource-windows-x86-5.12.10.exe 官方离线安装包 Download Source Package Offline Installers | Qt 下载巨慢&#xff08;也可能很快&#xff09; 只能下载到最新的&…...

RustDesk最新版本编译与打包

本文环境 主要参考&#xff1a; https://www.yuque.com/shikangsi/efy0cp/wei3g1?https://blog.csdn.net/hualuohuakai2014/article/details/121605631 问题 flutter 生成 bridge 文件。 先安装工具&#xff0c;再生成ffi文件。 PS C:\Users\Administrator> cargo ins…...

Gin 框架入门实战系列(一)

GIN介绍 Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点 对于golang而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错 借助框架开发,不仅可以省去很多常用的封装带来的时间,…...

【测试】pywinauto的简单使用(安装、常用对象、元素控件、鼠标操作、键盘操作)

1.说明 pywinauto是一个用于自动化Python 模块&#xff0c;适合Windows系统的软件&#xff08;GUI&#xff09;&#xff0c;可以通过Pywinauto遍历窗口&#xff08;对话框&#xff09;和窗口里的控件&#xff0c;也可以控制鼠标和键盘输入&#xff0c;所以它能做的事情比之前介…...

Java基础十八(正则表达式 + 日期时间)

1. 正则表达式 1.1 普通字符 字符描述示例[abc]匹配 […] 中所有字符[hlo] 匹配字符串 "hello world" 中所有的 h l o 字母[^ABC]匹配除了 […] 中所有字符[hlo] 匹配字符串 "hello world" 中除了 h l o 的所有字母[^a-z]匹配除了 […] 中所有字符[hlo] 匹…...

Linux C 多进程编程(面试考点)

嵌入式开发为什么要移植操作系统&#xff1f; 1.减小软硬件的耦合度&#xff0c;提高软件的移植性 2. 操作系统提供很多库和工具&#xff08;QT Open CV&#xff09;&#xff0c;提高开发效率 3.操作系统提供多任务机制&#xff0c;______________________? (提高C…...

c++一级

与7无关的数 #include<iostream> #include<iomanip> using namespace std; int main() {   int n,a,sum0,c0;   cin>>n;   for(int i1;i<n;i){     if(i%7!0){       ai;       c0; …...

Code Lab - 34

GAT里面有一些地方看的不是太懂&#xff08;GAT里Multi Attention的具体做法&#xff09;&#xff0c;暂时找了参考代码&#xff0c;留一个疑问 1. 一个通用的GNN Stack import torch_geometric import torch import torch_scatter import torch.nn as nn import torch.nn.fun…...

后端返回文件流,前端怎么导出、下载(8种方法可实现)

在前端导出和下载后端返回的文件流时&#xff0c;可以使用以下几种方法&#xff1a; 使用window.open()方法&#xff1a; 在前端使用window.open()方法打开一个新的窗口或标签页&#xff0c;并将后端返回的文件流作为URL传递给该方法。浏览器会自动下载该文件。例如&#xff1a…...

什么是 ThreadLocal?

ThreadLocal 是 Java 中的一个类,用于在多线程环境下,为每个线程提供独立的变量副本。每个线程可以通过 ThreadLocal 存储和获取数据,而不会影响其他线程的数据。这在某些情况下非常有用,特别是当多个线程需要访问共享数据,但又希望保持数据的隔离性时。 ThreadLocal 主要…...

CANOCO5.0实现冗余分析(RDA)最详细步骤

在地理及生态领域会常使用RDA分析&#xff0c;RDA的实现路径也有很多&#xff0c;今天介绍一下CANOCO软件的实现方法。 1.软件安装 时间调整到2010年 2.数据处理 得有不同的物种或者样点数值&#xff0c;再加上环境因子数据。 3.软件运行 4.结果解读 结果解读主要把握这几点…...

【tkinter 专栏】掷骰子游戏

文章目录 前言本章内容导图1. 需求分析2. 系统功能结构3. 设计流程4. 系统开发环境5. 系统预览6. 窗口布局7. 功能实现用户和电脑选择骰子的点数大小摇骰子过程实现判断游戏结果单击开始按钮进行游戏源代码汇总前言 本专栏将参考《Python GUI 设计 tkinter 从入门到实践》书籍…...

19 NAT穿透|python高级

文章目录 网络通信过程NAT穿透 python高级GIL锁深拷贝与浅拷贝私有化import导入模块工厂模式多继承以及 MRO 顺序烧脑题property属性property装饰器property类属性 魔法属性\_\_doc\_\_\_\_module\_\_ 和 \_\_class\_\_\_\_init\_\_\_\_del\_\_\_\_call\_\_\_\_dict\_\_\_\_str…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程

鸿蒙电脑版操作系统来了&#xff0c;很多小伙伴想体验鸿蒙电脑版操作系统&#xff0c;可惜&#xff0c;鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机&#xff0c;来体验大家心心念念的鸿蒙系统啦&#xff01;注意&#xff1a;虚拟…...

Android屏幕刷新率与FPS(Frames Per Second) 120hz

Android屏幕刷新率与FPS(Frames Per Second) 120hz 屏幕刷新率是屏幕每秒钟刷新显示内容的次数&#xff0c;单位是赫兹&#xff08;Hz&#xff09;。 60Hz 屏幕&#xff1a;每秒刷新 60 次&#xff0c;每次刷新间隔约 16.67ms 90Hz 屏幕&#xff1a;每秒刷新 90 次&#xff0c;…...

理想汽车5月交付40856辆,同比增长16.7%

6月1日&#xff0c;理想汽车官方宣布&#xff0c;5月交付新车40856辆&#xff0c;同比增长16.7%。截至2025年5月31日&#xff0c;理想汽车历史累计交付量为1301531辆。 官方表示&#xff0c;理想L系列智能焕新版在5月正式发布&#xff0c;全系产品力有显著的提升&#xff0c;每…...