springMVC学习
概述
Spring MVC(Model-View-Controller,模型-视图-控制器)是Spring框架的一部分,用于构建基于Java的Web应用程序。它遵循MVC设计模式,分离了应用程序的不同方面(输入逻辑、业务逻辑和UI逻辑),从而实现松耦合和模块化。
主要组件
主控:DispatcherServlet 前端控制器
三大组件:Handler Mapping -> HandlerAdapter -> View Resolver
-
DispatcherServlet 前端控制器:
- 核心组件,是前端控制器(Front Controller)模式的实现。
- 接收所有的HTTP请求,并将其分发给适当的处理器(Controller)。
-
Handler Mapping 处理器映射器:
- 将请求映射到具体的处理器(Controller)。
- 可以基于URL、注解、请求参数等进行映射。
-
HandlerAdapter 处理器适配器
-
Controller:
- 处理请求的具体组件。
- 通常是一个带有特定注解(如
@Controller、@RequestMapping)的类或方法。 - 从Model中获取数据并将其返回给视图(View)。
-
ModelAndView:
- 包含模型数据和视图信息的对象。
- Controller处理完请求后,返回一个ModelAndView对象,交给DispatcherServlet。
-
View Resolver 视图解析器:
- 根据逻辑视图名解析实际的视图实现。
- 常见的视图技术有JSP、Thymeleaf、FreeMarker等。
-
View:
- 负责呈现最终结果给用户。
- 使用模型数据生成响应内容。
HandlerAdapter处理器适配器中的设计模式
在Spring MVC中,HandlerAdapter主要使用了以下设计模式:
1. 适配器模式(Adapter Pattern)
定义:适配器模式用于将一个接口转换为客户端期望的另一个接口,使得原本由于接口不兼容而无法一起工作的类能够一起工作。
在Spring MVC中的应用:
HandlerAdapter接口是适配器模式的典型例子。Spring MVC通过HandlerAdapter将不同类型的处理器(如Controller)适配为统一的处理方式。- Spring MVC支持多种处理器类型,如传统的Controller接口实现、注解驱动的控制器等。每种处理器类型都有相应的
HandlerAdapter实现,将其转换为DispatcherServlet可以处理的格式。 - 例如,
RequestMappingHandlerAdapter适配了基于注解的控制器,SimpleControllerHandlerAdapter适配了传统的实现Controller接口的控制器。
2. 策略模式(Strategy Pattern)
定义:策略模式定义了一系列算法或行为,并将它们封装起来,使它们可以互换。策略模式让算法独立于使用它的客户端变化。
在Spring MVC中的应用:
HandlerAdapter接口本身体现了策略模式。不同的HandlerAdapter实现了不同的策略,处理不同类型的请求处理器。DispatcherServlet作为客户端,使用不同的HandlerAdapter策略来处理不同的控制器类型。这使得Spring MVC能够灵活地扩展和适应新的控制器类型,而无需修改核心代码。
3. 工厂模式(Factory Pattern)
定义:工厂模式用于创建对象,而无需指定创建对象的具体类。工厂模式通过定义一个创建对象的接口,将实际创建工作推迟到子类中。
在Spring MVC中的应用:
- Spring的应用上下文(ApplicationContext)和Web上下文(WebApplicationContext)使用了工厂模式来管理和创建
HandlerAdapter实例。 - 在配置Spring MVC时,可以通过配置文件或注解声明哪些
HandlerAdapter应该被创建和使用,Spring框架会负责实际的对象创建和依赖注入。
具体示例
假设有一个简单的基于注解的控制器:
@Controller
public class MyController {@RequestMapping("/hello")public String handleRequest() {return "hello";}
}
对于上述控制器,Spring MVC的工作流程如下:
- DispatcherServlet接收请求。
- 使用HandlerMapping找到相应的处理器(即
MyController)。 - DispatcherServlet使用适当的HandlerAdapter(如
RequestMappingHandlerAdapter)来调用处理器。 RequestMappingHandlerAdapter将MyController的请求处理方法适配为通用的处理方式,返回视图名。
通过适配器模式,Spring MVC能够统一处理不同类型的控制器,使得框架更加灵活和可扩展。
工作流程
执行时序图

- 客户端发送HTTP请求。
- DispatcherServlet接收请求。
- DispatcherServlet通过Handler Mapping找到适当的Controller。
- Controller处理请求,操作Model,生成ModelAndView对象。
- DispatcherServlet通过View Resolver解析逻辑视图名,找到实际的View实现。
- View使用Model数据生成响应内容,返回给客户端。
执行原理图

核心注解
- @Controller: 标识一个类为Controller。
- @RequestMapping: 用于映射请求到具体的处理器方法。
- @GetMapping, @PostMapping, @PutMapping, @DeleteMapping: 更具体的请求映射注解。
- @RequestParam: 绑定请求参数到方法参数。
- @PathVariable: 绑定URL模板变量到方法参数。
- @ModelAttribute: 绑定请求参数到模型对象。
示例代码
@Controller
public class HelloController {@RequestMapping("/hello")public ModelAndView hello(@RequestParam("name") String name) {ModelAndView mav = new ModelAndView();mav.setViewName("hello");mav.addObject("message", "Hello, " + name);return mav;}
}
配置文件示例(XML)
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><mvc:annotation-driven /><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/" /><property name="suffix" value=".jsp" /></bean><bean class="com.example.HelloController" />
</beans>
优点
- 松耦合: 通过MVC模式分离关注点。
- 灵活性: 支持多种视图技术和模板引擎。
- 易扩展: 可以通过配置和注解轻松扩展功能。
- 集成性: 与Spring生态系统的其他部分无缝集成,如Spring Security、Spring Data等。
Spring MVC是一个强大且灵活的Web框架,适用于从小型到大型的Web应用开发。通过它,开发者可以快速构建、测试和维护高质量的Java Web应用程序。
比较传统方法
使用传统的Servlet和JSP技术来改写示例代码。传统方法下,我们需要手动处理请求,管理视图以及传递数据。以下是相应的实现:
目录结构
|-- src
| |-- main
| |-- java
| | |-- com
| | |-- example
| | |-- HelloServlet.java
| |-- webapp
| |-- WEB-INF
| |-- views
| | |-- hello.jsp
| |-- web.xml
HelloServlet.java
package com.example;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String name = request.getParameter("name");if (name == null || name.isEmpty()) {name = "World";}request.setAttribute("message", "Hello, " + name);request.getRequestDispatcher("/WEB-INF/views/hello.jsp").forward(request, response);}
}
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Hello</title>
</head>
<body><h1>${message}</h1>
</body>
</html>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"version="2.5"><servlet><servlet-name>HelloServlet</servlet-name><servlet-class>com.example.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping>
</web-app>
工作流程
- 客户端发送请求:用户在浏览器中输入
http://localhost:8080/your-app-context/hello?name=John。 - Servlet接收请求:
HelloServlet的doGet方法处理这个请求。 - 参数处理:Servlet从请求中获取参数
name,如果没有传递参数,默认值为"World"。 - 设置请求属性:Servlet将生成的消息作为请求属性
message存储。 - 请求转发:Servlet使用
RequestDispatcher将请求转发到hello.jsp。 - 视图生成:
hello.jsp使用请求属性message生成响应内容并返回给客户端。
解释
- Servlet:代替了Spring MVC的Controller,用于处理HTTP请求。
- RequestDispatcher:用于将请求转发到JSP页面,类似于Spring MVC中的View Resolver。
- JSP:负责生成最终的HTML响应,类似于Spring MVC中的视图。
这种方法没有Spring MVC那样的模块化和灵活性,但它展示了在没有Spring MVC框架支持下,如何使用Servlet和JSP技术处理请求和生成视图。
相关文章:
springMVC学习
概述 Spring MVC(Model-View-Controller,模型-视图-控制器)是Spring框架的一部分,用于构建基于Java的Web应用程序。它遵循MVC设计模式,分离了应用程序的不同方面(输入逻辑、业务逻辑和UI逻辑)&…...
深入探讨光刻技术:半导体制造的关键工艺
前言 光刻(Photolithography)是现代半导体制造过程中不可或缺的一环,它的精度和能力直接决定了芯片的性能和密度。本文将详细介绍光刻技术的基本原理、过程、关键技术及其在半导体制造中的重要性。 光刻技术的基本原理 光刻是一种利用光化…...
CesiumJS【Basic】- #042 绘制纹理线(Primitive方式)
文章目录 绘制纹理线(Primitive方式)1 目标2 代码2.1 main.ts3 资源文件绘制纹理线(Primitive方式) 1 目标 使用Primitive方式绘制纹理线 2 代码 2.1 main.ts var start = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883);var...
代码随想录第38天|动态规划
1049. 最后一块石头的重量 II 参考 备注: 当物体容量也等同于价值时, 01背包问题的含义则是利用好最大的背包容量sum/2, 使得结果尽可能的接近或者小于 sum/2 等价: 尽可能的平分成相同的两堆, 其差则为结果, 比如 (abc)-d, (ac)-(bd) , 最终的结果是一堆减去另外一堆的和, 问…...
java生成excel,uniapp微信小程序接收excel并打开
java引包,引的是apache.poi <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency> 写一个测试类,把excel输出到指定路径 public s…...
sam_out 目标检测的应用
缺点参考地址训练验证模型解析 缺点 词表太大量化才可 参考地址 https://aistudio.baidu.com/projectdetail/8103098 训练验证 import os from glob import glob import cv2 import paddle import faiss from out_yolo_model import GPT as GPT13 import pandas as pd imp…...
VLAN原理与配置
AUTHOR :闫小雨 DATE:2024-04-28 目录 VLAN的三种端口类型 VLAN原理 什么是VLAN 为什么使用VLAN VLAN的基本原理 VLAN标签 VLAN标签各字段含义如下: VLAN的划分方式 VLAN的划分包括如下5种方法: VLAN的接口链路类型 创建V…...
使用Spring Boot实现RESTful API
使用Spring Boot实现RESTful API 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨如何利用Spring Boot框架实现RESTful API,这是现…...
中英双语介绍美国常春藤联盟( Ivy League):八所高校
中文版 常春藤联盟简介 常春藤联盟(Ivy League)是美国东北部八所私立大学组成的高校联盟。虽然最初是因体育联盟而得名,但这些学校以其学术卓越、历史悠久、校友杰出而闻名于世。以下是对常春藤联盟的详细介绍,包括其由来、成员…...
【计算机网络】常见的网络通信协议
目录 1. TCP/IP协议 2. HTTP协议 3. FTP协议 4. SMTP协议 5. POP3协议 6. IMAP协议 7. DNS协议 8. DHCP协议 9. SSH协议 10. SSL/TLS协议 11. SNMP协议 12. NTP协议 13. VoIP协议 14. WebSocket协议 15. BGP协议 16. OSPF协议 17. RIP协议 18. ICMP协议 1…...
java实现http/https请求
在Java中,有多种方式可以实现HTTP或HTTPS请求。以下是使用第三方库Apache HttpClient来实现HTTP/HTTPS请求的工具类。 优势和特点 URIBuilder的优势在于它提供了一种简单而灵活的方式来构造URI,帮助开发人员避免手动拼接URI字符串,并处理参…...
NC204871 求和
链接 思路: 对于一个子树来说,子树的节点就包括在整颗树的dfs序中子树根节点出现的前后之间,所以我们先进行一次dfs,用b数组的0表示区间左端点,1表示区间右端点,同时用a数组来标记dfs序中的值。处理完dfs序…...
git克隆代码warning: could not find UI helper ‘git-credential-manager-ui‘
git克隆代码warning: could not find UI helper ‘git-credential-manager-ui’ 方案 git config --global --unset credential.helpergit-credential-manager configure...
Generator 是怎么样使用的以及各个阶段的变化如何
Generators 是 JavaScript 中一种特殊类型的函数,可以在执行过程中暂停,并且在需要时恢复执行。它们是通过 function* 关键字来定义的。Generator 函数返回的是一个迭代器对象,通过调用该迭代器对象的 next() 方法来控制函数的执行。在调用 n…...
一文了解Java中 Vector、ArrayList、LinkedList 之间的区别
目录 1. 数据结构 Vector 和 ArrayList LinkedList 2. 线程安全 Vector ArrayList 和 LinkedList 3. 性能 插入和删除操作 随机访问 4. 内存使用 ArrayList 和 Vector LinkedList 5. 迭代器行为 ArrayList 和 Vector LinkedList 6. 扩展策略 ArrayList Vecto…...
【论文复现|智能算法改进】基于自适应动态鲸鱼优化算法的路径规划研究
目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 SCI二区|鲸鱼优化算法(WOA)原理及实现【附完整Matlab代码】 2.改进点 非线性收敛因子 WOA 主要通过控制系数向量 A 来决定鲸鱼是搜索猎物还是捕获猎物,即系数向量 A 可…...
【Win测试】窗口捕获的学习笔记
2 辨析笔记 2.1 mss:捕获屏幕可见区域,不适合捕获后台应用 Claude-3.5-Sonnet: MSS库可以用来捕获屏幕上可见的内容;然而,如果游戏窗口被其他窗口完全遮挡或最小化,MSS将无法捕获到被遮挡的游戏窗口内容,而…...
PostgreSQL的学习心得和知识总结(一百四十七)|深入理解PostgreSQL数据库之transaction chain的使用和实现
目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《PostgreSQL数据库内核分析》 2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》 3、PostgreSQL数据库仓库…...
宝塔linux网站迁移步骤
网站迁移到新服务器步骤 1.宝塔网站迁移,有个一键迁移工具,参考官网 宝塔一键迁移API版本 3.0版本教程 - Linux面板 - 宝塔面板论坛 (bt.cn)2 2.修改域名解析为新ip 3.如果网站没有域名,而是用ip访问的,则新宝塔数据库的wp_o…...
电路笔记(三极管器件): MOSFETIGBT
MOSFET vs IGBT MOSFET主要用于低电压和功率系统,而IGBT更适合高电压和功率系统。 1. MOSFET(金属氧化物半导体场效应晶体管) 优势: 高开关速度和响应速度,适合高频应用。(IGBT不适合高频应用,…...
CircuitPython硬件编程在Linux单板机上的实现:以ODROID C2为例
1. 项目概述:当CircuitPython遇见Linux单板机如果你玩过树莓派Pico或者Adafruit的Feather开发板,肯定对CircuitPython不陌生。它让Python跑在了微控制器上,用几行代码就能点亮LED、读取传感器,对硬件新手和快速原型开发来说&#…...
基于LLM的MUD游戏AI智能体框架:从感知-思考-行动循环到工程实践
1. 项目概述:一个面向MUD游戏的智能体框架最近在折腾AI智能体(Agent)相关的项目,发现了一个挺有意思的仓库:zn0nz/mud_agent。乍一看名字,可能很多朋友会有点懵,MUD是什么?Agent又怎…...
基于TRRS Trinkey的辅助技术设备开发:从接口转换到可编程交互
1. 项目概述:当辅助技术遇上可编程硬件如果你接触过辅助技术(Assistive Technology, AT),或者身边有朋友需要借助特殊设备与数字世界交互,你可能会发现,市面上很多现成的开关、控制器要么功能单一ÿ…...
Qgis二次开发-QgsAnnotationItem实战:构建交互式地图标注系统(文字、SVG、PNG/JPG)
1. QgsAnnotationItem基础概念与核心组件 在Qgis二次开发中,标注系统是增强地图表现力的重要工具。QgsAnnotationItem作为标注绘制的抽象基类,与我们熟悉的传统标注(QgsAnnotation)有本质区别——它专为QgsAnnotationLayer设计&am…...
深入解析浮点数内存存储与IEEE 754标准:从0.1+0.2≠0.3说起
1. 从一次“诡异”的计算错误说起前几天,一个刚入行的同事跑来找我,一脸困惑地给我看了一段Python代码。他写了个简单的循环累加,想计算0.1加10次,理论上应该等于1.0。但打印出来的结果却是0.9999999999999999。他反复检查了代码&…...
【Proteus仿真】SRF04超声波阈值预警系统设计与LCD1602交互实现
1. SRF04超声波测距原理与硬件连接 SRF04超声波模块是工业测距的经典选择,它通过发射40kHz的声波并计算回波时间差来测量距离。在实际项目中,我发现很多初学者容易忽略声速受温度影响的问题——常温下声速约343m/s,但温度每升高1℃࿰…...
UTF8-CPP跨版本兼容性指南:从C++98到C++20的完整支持
UTF8-CPP跨版本兼容性指南:从C98到C20的完整支持 【免费下载链接】utfcpp UTF-8 with C in a Portable Way 项目地址: https://gitcode.com/gh_mirrors/ut/utfcpp UTF8-CPP是一个轻量级的C库,专注于以可移植的方式提供UTF-8编码和解码功能&#x…...
令牌管理实战:从JWT原理到token-ninja库的集成与应用
1. 项目概述:一个专为令牌处理而生的“忍者”如果你在开发中经常和令牌(Token)打交道,比如处理JWT、API密钥、会话标识,或者是在构建需要精细权限控制的微服务、身份认证系统,那你一定遇到过这些麻烦&#…...
嵌入式以太网模块WIZ5500应用指南:从SPI接口到物联网稳定连接
1. 项目概述:为什么你的物联网项目需要一个有线网络“锚点”无线网络(Wi-Fi)确实方便,但做过几个实际项目的朋友都知道,它的“方便”有时是建立在“不确定性”之上的。信号波动、信道拥堵、复杂的认证流程,…...
开源HR智能体:基于LLM与Agent架构的自动化HR流程实践
1. 项目概述:一个开源的HR智能体最近在关注AI如何真正落地到具体业务场景,而不是停留在概念演示。一个让我眼前一亮的项目是ArjunFrancis/openhr-agent。简单来说,这是一个开源的、基于大语言模型(LLM)的HR(…...
