Java Spring MVC -01
SpringMVC 是一种基于 的实现 MVC 设计模式的请求驱动类型的轻量级 Web 框架,属于 Spring FrameWork 的后续产品,已经融合在 Spring Web Flow 中。
First:SpringMVC-01-SpringMVC 概述
SpringMVC 是 Spring 框架的一个模块,用于构建 Web 应用程序。它遵循 MVC (Model-View-Controller) 架构模式,将请求处理、业务逻辑和视图展示分离,使代码结构清晰,易于维护和测试。
SpringMVC 的主要特点:
-轻量级,非侵入式
-强大的请求映射机制
-支持多种视图技术
-强大的异常处理机制
-支持文件上传
-国际化和本地化支持
-支持 RESTful 风格的 URL
SpringMVC-02-SpringMVC 入门案例
下面是一个简单的 SpringMVC 入门案例,展示了如何创建一个基本的 Web 应用。
1. 添加 Maven 依赖
这些依赖是构建 SpringMVC 应用的基础:
xml:
<dependencies>
<!-- Spring MVC核心库 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.18</version>
</dependency>
<!-- Servlet API (由容器提供,无需打包) -->
<dependency>
<groupId>x.servlet</groupId>
<artifactId>x.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- JSP支持 (用于视图渲染) -->
<dependency>
<groupId>x.servlet.jsp</groupId>
<artifactId>x.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
关键依赖说明:
spring-webmvc:SpringMVC 框架的核心库
x.servlet-api:Servlet 容器接口
x.servlet.jsp-api:JSP 页面支持
2. Servlet 初始化类(AppInitializer)
这个类替代了传统的 web.xml 配置,用于注册 DispatcherServlet:
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null; // 根应用上下文配置(通常包含服务层和数据访问层)
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class }; // Web层配置
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" }; // 映射所有请求到DispatcherServlet
}
}
核心作用:
自动注册 Spring MVC 的前端控制器DispatcherServlet
指定配置类位置
映射请求路径
3. Spring 配置类(WebConfig)
配置 SpringMVC 的核心组件:
@Configuration
@EnableWebMvc // 启用Spring MVC注解支持
@ComponentScan(basePackages = "com.example.controller") // 扫描控制器
public class WebConfig {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/"); // JSP文件位置
resolver.setSuffix(".jsp"); // 文件后缀
return resolver;
}
}
关键配置项:
@EnableWebMvc:启用 Spring MVC 注解驱动
ComponentScan:扫描@Controller注解的类
ViewResolver:配置视图解析器,将逻辑视图名映射到物理 JSP 文件
4. 控制器(HelloController)
处理 HTTP 请求并返回视图:
@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(method = RequestMethod.GET)
public String sayHello(Model model) {
model.addAttribute("message", "Hello Spring MVC!");
return "hello"; // 逻辑视图名
}
}
核心注解:
@Controller:声明这是一个 Spring MVC 控制器
@RequestMapping:映射请求路径和 HTTP 方法
Model:用于传递数据到视图
5. JSP 视图(hello.jsp)
渲染最终响应页面:
jsp
<!DOCTYPE html>
<html>
<head>
<title>Hello Spring MVC</title>
</head>
<body>
<h1>${message}</h1> <!-- 接收控制器传递的数据 -->
</body>
</html>
关键技术点:
EL 表达式 (${message}):用于获取模型数据
视图位置:/WEB-INF/views/hello.jsp(由 ViewResolver 配置决定)
入门案例工作流程解析
当访问http://localhost:8080/hello时:
请求到达DispatcherServlet(由 AppInitializer 注册)
DispatcherServlet 通过 HandlerMapping 找到对应的HelloController
执行sayHello()方法,将数据存入 Model
返回逻辑视图名 "hello"
ViewResolver 将 "hello" 解析为 / WEB-INF/views/hello.jsp
JSP 页面渲染并返回响应
SpringMVC-03 - 入门案例工作流程解析
SpringMVC 的工作流程可以概括为以下几个步骤:
客户端发送请求到 DispatcherServlet
DispatcherServlet 接收请求并查询 HandlerMapping 找到处理该请求的 Controller
DispatcherServlet 调用 HandlerAdapter 来执行 Controller
Controller 处理请求并返回一个 ModelAndView 对象给 HandlerAdapter
HandlerAdapter 将 ModelAndView 返回给 DispatcherServlet
DispatcherServlet 查询 ViewResolver 找到与 ModelAndView 中逻辑视图名对应的实际视图
DispatcherServlet 将模型数据传递给视图
视图渲染结果返回给客户端
SpringMVC-04-bean 加载控制
在 SpringMVC 中,有两种类型的 ApplicationContext:
root 上下文 (Root ApplicationContext):包含应用的业务逻辑、数据访问等 Bean
Servlet 上下文 (Servlet ApplicationContext):包含控制器、视图解析器等 Web 相关 Bean
可以通过配置来控制哪些 Bean 被加载到哪个上下文:
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
@Configuration
@ComponentScan(basePackages = "com.example.service, com.example.repository")
public class RootConfig {
// 根上下文配置
}
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example.controller")
public class WebConfig {
// Servlet上下文配置
}
SpringMVC-05-PostMan 工具介绍
Postman 是一个用于测试 API 的工具,它可以发送各种 HTTP 请求 (GET、POST、PUT、DELETE 等),设置请求头、请求参数、请求体等,并查看响应结果。
使用 Postman 测试 SpringMVC API 的步骤:
打开 Postman,创建一个新的请求
选择请求方法 (GET、POST 等)
输入请求 URL
设置请求头 (如 Content-Type)
设置请求参数或请求体
点击发送按钮查看响应结果
SpringMVC-06 - 设置请求映射路径
在 SpringMVC 中,可以使用 @RequestMapping 注解来设置请求映射路径。该注解可以应用于类和方法上。
@Controller
@RequestMapping("/products")
public class ProductController {
// 处理GET请求 /products
@RequestMapping(method = RequestMethod.GET)
public String listProducts(Model model) {
// 获取产品列表
return "products/list";
}
// 处理GET请求 /products/{id}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
//@GetMappeing (value = "{id}")
public String getProduct(@PathVariable("id") Long id, Model model) {
// 获取单个产品
return "products/detail";
}
// 处理POST请求 /products
@RequestMapping(method = RequestMethod.POST)
public String addProduct(@ModelAttribute Product product) {
// 添加产品
return "redirect:/products";
}
}
SpringMVC-07-get 请求与 post 请求发送普通参数
一、GET 请求参数处理
1. 请求结构与参数传递
GET 请求将参数附加在 URL 的查询字符串中,格式为?参数名1=值1&参数名2=值2。例如:
http://localhost:8080/search?keyword=手机
浏览器发送的完整 HTTP 请求示例:
http:
GET /search?keyword=%E6%89%8B%E6%9C%BA HTTP/1.1
Host: localhost:8080User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: keep-alive
2. @RequestParam 注解详解
@Controller
@RequestMapping("/search")
public class SearchController {
// 基础用法
@GetMapping
public String search(@RequestParam("keyword") String keyword, Model model) {
// 处理搜索逻辑
List<Product> results = productService.search(keyword);
model.addAttribute("results", results);
return "search/results";
}
// 可选参数与默认值
@GetMapping("/advanced")
public String advancedSearch(
@RequestParam(value = "keyword", required = false) String keyword, // 可选参数
@RequestParam(value = "category", defaultValue = "all") String category, // 默认值
@RequestParam(value = "page", defaultValue = "1") int page,
@RequestParam(value = "size", defaultValue = "10") int size
) {
// 处理高级搜索
return "search/advanced";
}
// 绑定多个同名参数到List
@GetMapping("/filter")
public String filterProducts(@RequestParam("category") List<String> categories) {
// URL: /filter?category=手机&category=电脑
return "products/filter";
}}
3. 前端表单示例(GET 请求)
html
预览
<form action="/search" method="get">
<input type="text" name="keyword" placeholder="搜索关键词">
<select name="category">
<option value="all">全部</option>
<option value="phone">手机</option>
<option value="computer">电脑</option>
</select>
<button type="submit">搜索</button>
</form>
二、POST 请求参数处理
1. 请求结构与参数传递
POST 请求将参数封装在请求体中,需要指定Content-Type头。常见的Content-Type有:
application/x-www-form-urlencoded(默认)
multipart/form-data(文件上传)
application/json(JSON 数据)
浏览器发送的完整 HTTP 请求示例:
http:
POST /user/register HTTP/1.1Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
username=test&password=123456&email=test%40example.com
2. @RequestParam 处理简单参数
@Controller
@RequestMapping("/user")
public class UserController {
@PostMapping("/login")
public String login(
@RequestParam("username") String username,
@RequestParam("password") String password,
Model model
) {
User user = userService.validateUser(username, password);
if (user != null) {
return "redirect:/home";
} else {
model.addAttribute("error", "用户名或密码错误");
return "login";
}
}
}
3. @ModelAttribute 处理对象参数
// User类public class User {
private String username;
private String password;
private String email;
private Integer age;
// getters/setters
}
@Controller
@RequestMapping("/user")
public class UserController {
@PostMapping("/register")
public String register(@ModelAttribute User user) {//表单->User对象
// 自动将表单参数绑定到User对象
userService.register(user);
return "redirect:/user/login";
}
}
4. 前端表单示例(POST 请求)
html
<form action="/user/register" method="post">
用户名: <input type="text" name="username"><br>
密码: <input type="password" name="password"><br>
邮箱: <input type="email" name="email"><br>
年龄: <input type="number" name="age"><br>
<input type="submit" value="注册">
</form>
SpringMVC-08-5 种类型参数传递
SpringMVC 支持多种方式的参数传递:
路径变量 (Path Variable)
@RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
public String getUser(@PathVariable("id") Long id, Model model) {
// 处理逻辑
}
请求参数 (Request Parameter)
@RequestMapping(value = "/search", method = RequestMethod.GET)
public String search(@RequestParam("keyword") String keyword, Model model) {
// 处理逻辑
}
请求头 (Request Header)
@RequestMapping(value = "/download", method = RequestMethod.GET)
public ResponseEntity<byte[]> download(@RequestHeader("User-Agent") String userAgent) {
// 处理逻辑
}
Cookie 值
@RequestMapping(value = "/profile", method = RequestMethod.GET)
public String profile(@CookieValue("JSESSIONID") String sessionId, Model model) {
// 处理逻辑}
请求体 (用于 POST/PUT 请求)
@RequestMapping(value = "/users", method = RequestMethod.POST)
public ResponseEntity<User> createUser(@RequestBody User user) {
// 处理逻辑
}
SpringMVC-09-json 数据传递参数
在 RESTful API 中,通常使用 JSON 格式传递数据。可以使用 @RequestBody 和 @ResponseBody 注解来处理 JSON 数据。
首先需要添加 Jackson 依赖:
xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
控制器示例:
@RestController
@RequestMapping("/api/users")
public class UserRestController {
@PostMapping
public User createUser(@RequestBody User user) {//JSON->对象
// 创建用户
return userService.save(user);
}
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
// 获取用户
return userService.findById(id);
}
}
SpringMVC-10 - 日期型参数传递
SpringMVC 默认情况下可能无法正确解析日期参数,需要进行额外配置。
使用 @DateTimeFormat 注解:
@RequestMapping(value = "/events", method = RequestMethod.GET)
public String getEvents(@RequestParam("date")
@DateTimeFormat(pattern = "yyyy-MM-dd") //格式
LocalDate date, Model model) {
// 处理逻辑
}
全局日期格式化配置:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
registrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
registrar.registerFormatters(registry);
}
}
相关文章:
Java Spring MVC -01
SpringMVC 是一种基于 的实现 MVC 设计模式的请求驱动类型的轻量级 Web 框架,属于 Spring FrameWork 的后续产品,已经融合在 Spring Web Flow 中。 First:SpringMVC-01-SpringMVC 概述 SpringMVC 是 Spring 框架的一个模块,用于构建 Web 应…...

KV cache 缓存与量化:加速大型语言模型推理的关键技术
引言 在大型语言模型(LLM)的推理过程中,KV 缓存(Key-Value Cache) 是一项至关重要的优化技术。自回归生成(如逐 token 生成文本)的特性决定了模型需要反复利用历史token的注意力计算结果&#…...
视频编解码学习十一之视频原始数据
一、视频未编码前的原始数据是怎样的? 视频在未编码前的原始数据被称为 原始视频数据(Raw Video Data),主要是按照帧(Frame)来组织的图像序列。每一帧本质上就是一张图片,通常采用某种颜色格式…...
[Java实战]Spring Boot 3 整合 Apache Shiro(二十一)
[Java实战]Spring Boot 3 整合 Apache Shiro(二十一) 引言 在复杂的业务系统中,安全控制(认证、授权、加密)是核心需求。相比于 Spring Security 的重量级设计,Apache Shiro 凭借其简洁的 API 和灵活的扩…...
Cursor 编辑器 的 高级使用技巧与创意玩法
以下是针对 Cursor 编辑器 的 高级使用技巧与创意玩法 深度解析,涵盖代码生成优化、工作流定制、隐藏功能等层面,助你将 AI 辅助编程效率提升至新高度: 一、代码生成进阶技巧 1. 精准控制生成粒度 行级控制: 在代码行内用 // > 指定生成方向(替代模糊注释)def merge_…...
mysql性能提升方法大汇总
前言 最近在开发自己的小程序的时候,由于业务功能对系统性能的要求很高,系统性能损耗又主要在mysql上,而业务功能的数据表很多,单表数据量也很大,又涉及到很多场景的数据查询,所以我针对mysql调用做了优化…...
C++标准流详解:cin/cout的绑定机制与cerr/clog的缓冲差异
在C中,标准错误流(cerr)、标准日志流(clog)与标准输入输出流(cin/cout)的行为差异主要体现在缓冲机制和绑定关系上。以下是详细解释,并结合cin和cout的关联性进行对比分析࿱…...

BlockMesh Ai项目 监控节点部署教程
项目介绍 BlockMesh 是一个创新、开放且安全的网络,允许用户轻松地将多余的带宽货币化。 它为用户提供了被动获利并参与人工智能数据层、在线隐私、开源和区块链行业前沿的绝佳机会。 此教程为Linux系统教程 教程开始 首先到这里注册账号,注册后保存…...

【Bluedroid】蓝牙 HID DEVICE 初始化流程源码解析
本文深入剖析Android蓝牙协议栈中HID设备(BT-HD)服务的初始化与启用流程,从接口初始化、服务掩码管理、服务请求路由到属性回调通知,完整展现蓝牙HID服务激活的技术路径。通过代码逻辑梳理,揭示服务启用的核心机制&…...

iOS创建Certificate证书、制作p12证书流程
一、创建Certificates 1、第一步得先在苹果电脑上创建一个.certSigningRequest的文件。首先打开钥匙串,使用快捷键【command空格】——输入【钥匙串】回车(找不到就搜一下钥匙串访问使用手册) 2、然后在苹果电脑的左上角菜单栏选择【钥匙串…...

curl发送数据不为null,但是后端接收到为null
curl -X POST http://localhost:8080/xiaozhi/test --header "Content-Type: application/json" -d "{\"age\":123}"经过检查发现注解导入错误 正确的应该是 import org.springframework.web.bind.annotation.RequestBody;...

blazor与硬件通信实现案例
在网页接入硬件交互通信方案这篇博客中,曾经提到了网页中接入各种硬件操作的方法,即通过Windows Service作为指令的中转,并建立websocket通信连接,进而实现接入硬件的各种操作。这篇博客就以实际的案例来讲解具体怎么实现。 一、建立Windows Service项目 比如我就建立了一…...

Linux下mysql的安装与远程链接
linux安装mysql 01下载依赖: 找到网址/download下: 最下面MySQL Community(mysql社区版) 选择MySQL Community Server 选择对应的mysql版本 操作系统版本选择 根据操作系统的版本选择具体版本号 下载离线版本 安装包详情 0…...
esp32硬件支持AT指令
步骤1:下载AT固件 从乐鑫官网或Git鑫GitHub仓库(https://github.com/espressif/esp-at)获取对应ESP32型号的AT固件(如ESP32-AT.bin)。 步骤2:安装烧录工具 使用 esptool.py(命令行工具&#…...

【HT周赛】T3.二维平面 题解(分块:矩形chkmax,求矩形和)
题意 需要维护 n n n \times n nn 平面上的整点,每个点 ( x , y ) (x, y) (x,y) 有权值 V ( x , y ) V(x, y) V(x,y),初始都为 0 0 0。 同时给定 n n n 次修改操作,每次修改给出 x 1 , x 2 , y 1 , y 2 , v x_1, x_2, y_1, y_2, v x…...
C++中的虚表和虚表指针的原理和示例
一、基本概念 1. 什么是虚函数(virtual function)? 虚函数是用 virtual 关键字修饰的成员函数,支持运行时多态(dynamic polymorphism)。通过基类指针或引用调用派生类重写的函数。 class Base { public:…...

qemu热迁移后内存占用突增问题
1.问题描述 虚拟机配置了memoryBackingmemfd的情况下,热迁移虚拟机后,在目的节点 qemu-kvm 进程占用 rss 会突增很多。 如果去掉这个配置没这个现象。 <memoryBacking><source typememfd/> </memoryBacking>2.问题现象 2.1 不配置…...

鸿蒙 Core File Kit(文件基础服务)之简单使用文件
查看常用的沙箱目录 应用沙箱文件访问关系图 应用文件目录结构图 查看常用的沙箱目录 Entry Component struct Index {build() {Button(查看常用的沙箱目录).onClick(_>{let ctx getContext() // UI下只能使用这个方法,不能 this.contextconsole.log(--应用缓存…...
AI 检测原创论文:技术迷思与教育本质的悖论思考
当高校将 AI 写作检测工具作为学术诚信的 "电子判官",一场由技术理性引发的教育异化正在悄然上演。GPT-4 检测工具将人类创作的论文误判为 AI 生成的概率高达 23%(斯坦福大学 2024 年研究数据),这种 "以 AI 制 AI&…...

基于Qt的app开发第七天
写在前面 笔者是大一下计科生,标题这个项目是笔者这个学期的课设,与学长共创,我负责客户端部分,现在已经实现了待办板块的新建、修改。 这个项目目前已经走上正轨了,博主也实现了主要功能的从无到有ÿ…...

目标检测任务常用脚本1——将YOLO格式的数据集转换成VOC格式的数据集
在目标检测任务中,不同框架使用的标注格式各不相同。常见的框架中,YOLO 使用 .txt 文件进行标注,而 PASCAL VOC 则使用 .xml 文件。如果你需要将一个 YOLO 格式的数据集转换为 VOC 格式以便适配其他模型,本文提供了一个结构清晰、…...

NLTK库: 数据集3-分类与标注语料(Categorized and Tagged Corpora)
NLTK库: 数据集3-分类与标注语料(Categorized and Tagged Corpora) 1.二分类语料 主要是电影语料,和情绪(积极消极、主观客观)有关,有以下2个语料: 1.1 movie_reviews: IMDb 影评 IMDb(Internet Movie …...

uni-app学习笔记五-vue3响应式基础
一.使用ref定义响应式变量 在组合式 API 中,推荐使用 ref() 函数来声明响应式状态,ref() 接收参数,并将其包裹在一个带有 .value 属性的 ref 对象中返回 示例代码: <template> <view>{{ num1 }}</view><vi…...

ElasticSeach快速上手笔记-入门篇
由来 Elasticsearch 是一个基于 Apache Lucene 构建的分布式、高扩展、近实时的搜索与数据分析引擎,能够高效处理结构化和非结构化数据的全文检索及复杂分析 搜索,即用户在平台如百度进行输入关键词,由后端给出搜索结果数据进行返回&#x…...
eward hacking 问题 强化学习钻空子
Reward Hacking的本质是目标对齐(Goal Alignment)失败 “Reward hacking”(奖励黑客)是强化学习或AI系统中常见的问题,通俗地说就是: AI模型“钻空子”,用投机取巧的方式来拿高分,而…...
uniapp开发4--实现耗时操作的加载动画效果
下面是使用 Vue 组件的方式,在 uni-app 中封装耗时操作的加载动画效果及全屏遮罩层的组件的示例。 组件结构: components/loading.vue: 组件文件,包含 HTML 结构、样式和 JS 逻辑。 代码: <template><view class&…...

《ffplay 读线程与解码线程分析:从初始化到 seek 操作,对比视频与音频解码的差异》
1 read-thread 1.1 初始化部分 1.分配. avformat_alloc_context 创建上下⽂ ic avformat_alloc_context();if (!ic) {av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");ret AVERROR(ENOMEM);goto fail;}2 ic->interrupt_callback.callback deco…...

MySQL推荐书单:从入门到精通
给大家介绍一些 MySQL 从入门到精通的经典书单,可以基于不同学习阶段的需求进行选择。 入门 MySQL必知必会 这本书继承了《SQL必知必会》的优点,专门针对 MySQL 用户,没有过多阐述数据库基础理论,而是紧贴实战,直接从…...
用 Rust 搭建一个优雅的多线程服务器:从零开始的详细指南
嘿,小伙伴们!今天咱们来聊聊怎么用 Rust 搭建一个牛气哄哄的多线程服务器,还能在需要的时候优雅地关机。为啥要用 Rust 呢?因为 Rust 是个超级靠谱的语言,它能保证内存安全,写并发代码的时候不用担心那些让…...
redis 数据结构-01( SET、GET、DEL)
使用 Redis 字符串:SET、GET、DEL Redis 字符串是用于存储和操作文本或二进制数据的基本数据类型。它们是 Redis 中最简单但功能最丰富的数据结构,可作为构建更复杂结构的基石。了解如何有效地使用字符串对于充分利用 Redis 的缓存、会话管理以及其他各…...