SpringMVC实战:动态时钟

引言

在现代 Web 开发中,选择一个合适的框架对于项目的成功至关重要。Spring MVC 作为 Spring 框架的核心模块之一,以其清晰的架构、强大的功能和高度的可配置性,成为了 Java Web 开发领域的主流选择。本文将通过一个“动态时钟”的实战项目,深入分析 Spring MVC 模式,并分享在开发过程中遇到的问题及解决方案。

Spring MVC 模式分析

什么是 Spring MVC?

Spring MVC 是一个基于 Java 的 Web 框架,它实现了著名的 模型-视图-控制器 (Model-View-Controller, MVC) 设计模式。它旨在分离应用程序的不同职责,使得开发人员能够更清晰地组织代码,提高可维护性和可扩展性。

MVC 模式的核心概念

在深入 Spring MVC 之前,我们先回顾一下 MVC 模式的三个核心组件:

  • Model (模型): 负责封装应用程序的数据和业务逻辑。它独立于用户界面,处理数据的存储、检索、更新和验证。在 Web 应用中,模型通常是 Java Bean 或 POJO (Plain Old Java Object)。

  • View (视图): 负责数据的展示,即用户界面。它从模型中获取数据,并以用户友好的方式呈现出来。视图通常不包含任何业务逻辑,只负责显示。在 Java Web 中,JSP (JavaServer Pages)、Thymeleaf、FreeMarker 等都可以作为视图技术。

  • Controller (控制器): 充当模型和视图之间的协调者。它接收用户的输入(通常是 HTTP 请求),处理这些输入,调用模型来执行相应的业务逻辑,然后选择合适的视图来显示结果。控制器本身不处理业务逻辑,它只是将请求转发给模型,并将模型的结果传递给视图。

Spring MVC 在 MVC 模式中的实现

Spring MVC 对 MVC 模式进行了精巧的实现,其核心是一个名为 DispatcherServlet 的前端控制器。以下是 Spring MVC 请求处理的典型流程:

  1. DispatcherServlet (前端控制器):

    • 作为整个 Spring MVC 应用程序的入口点,它拦截所有(或特定模式的)进来的 HTTP 请求。

    • 它的作用类似于一个总调度员,将请求分发给合适的处理器。

  2. Handler Mapping (处理器映射):

    • DispatcherServlet 接收到请求后,会查询 HandlerMapping

    • HandlerMapping 的职责是根据请求的 URL 路径,找到能够处理该请求的 处理器 (Handler),通常是带有 @Controller@RequestMapping 注解的控制器方法。

  3. Controller (控制器):

    • 找到对应的控制器方法后,DispatcherServlet 会调用该方法。

    • 控制器方法执行业务逻辑(可能通过调用服务层或数据访问层),处理请求参数,并准备需要展示给视图的数据。

    • 控制器通常返回一个 ModelAndView 对象或一个逻辑视图名,其中包含模型数据和视图信息。

  4. ModelAndView (模型和视图):

    • 这是一个封装了模型数据和逻辑视图名的对象。模型数据是键值对形式,视图名是字符串,用于标识要渲染的视图。

  5. View Resolver (视图解析器):

    • DispatcherServlet 接收到控制器返回的逻辑视图名后,会将其交给 ViewResolver

    • ViewResolver 的职责是将逻辑视图名解析为实际的视图资源(例如,一个 JSP 文件的路径)。在我们的项目中,InternalResourceViewResolver 会将 "clock" 解析为 /WEB-INF/views/clock.jsp

  6. View (视图):

    • 一旦 ViewResolver 找到实际的视图资源,DispatcherServlet 就会将模型数据传递给该视图。

    • 视图负责渲染模型数据,生成最终的 HTML、XML 或其他格式的响应,并将其发送回客户端浏览器。

Spring MVC 的优点

  • 职责分离清晰: 模型、视图、控制器各司其职,代码结构清晰,易于理解和维护。

  • 灵活性和可配置性: Spring MVC 提供了大量的可插拔组件(如 HandlerMappingViewResolver),允许开发人员根据需求进行高度定制。

  • 易于测试: 由于各层职责分离,控制器可以独立于视图和模型进行单元测试,提高了测试效率。

  • 强大的生态系统: 作为 Spring 框架的一部分,Spring MVC 可以无缝集成 Spring 的其他模块,如 Spring Security、Spring Data 等,提供全面的企业级解决方案。

  • RESTful 支持: 内置对 RESTful Web 服务的强大支持,使得构建 API 变得简单。

项目实战:动态时钟

项目目标

我们的目标是构建一个基于 Spring MVC 的 Web 应用程序,其中包含一个动态变化的模拟时钟。时钟的画面将通过 JSP 页面呈现,并利用前端技术(HTML、CSS、JavaScript)实现其动态效果和居中显示。

技术栈

  • 后端框架: Spring MVC

  • 视图技术: JSP (JavaServer Pages)

  • 前端样式: Tailwind CSS (通过 CDN 引入)

  • 前端逻辑: JavaScript (实现指针动态旋转)

  • 构建工具: Maven

  • 应用服务器: Apache Tomcat

项目结构概览

一个典型的 Spring MVC Web 项目结构如下:

your-clock-project/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           └── controller/
│   │   │               └── ClockController.java  <-- Spring MVC 控制器
│   │   ├── resources/
│   │   │   └── spring-mvc-config.xml           <-- Spring MVC 配置文件
│   │   └── webapp/
│   │       ├── WEB-INF/
│   │       │   ├── web.xml                     <-- Web 应用部署描述符
│   │       │      └── views/
│   │       │       └── clock.jsp               <-- JSP 视图页面
│   │       └── ...
├── pom.xml                                     <-- Maven 项目对象模型文件

关键文件说明:

  • pom.xml Maven 项目配置文件,管理项目依赖(Spring MVC、JSP API、Servlet API 等)和构建插件(如 maven-war-plugintomcat8-maven-plugin)。我们通过 <finalName>web10</finalName> 将 WAR 包名称设置为 web10.war

  • web.xml Web 应用程序部署描述符,配置 DispatcherServlet 作为前端控制器,并指定其 Spring MVC 配置文件的位置。

  • spring-mvc-config.xml Spring MVC 配置文件,启用注解驱动的 MVC,配置组件扫描(扫描控制器),并定义 InternalResourceViewResolver 来解析 JSP 视图。

  • ClockController.java Spring MVC 控制器,使用 @RequestMapping("/clock") 将 HTTP GET 请求映射到 showClockPage() 方法,该方法返回逻辑视图名 "clock"

  • clock.jsp JSP 视图页面,包含动态时钟的 HTML 结构、Tailwind CSS 样式和 JavaScript 逻辑。前端 JavaScript 负责获取当前时间并实时更新时针、分针、秒针的旋转角度,实现动态效果。

部署与运行

  1. 构建 WAR 包: 在项目根目录运行 mvn clean install 命令,将在 target/ 目录下生成 web10.war 文件。

  2. 部署到 Tomcat:

    • 手动部署:web10.war 复制到 Tomcat 安装目录下的 webapps 文件夹。

    • 使用 Maven 插件:pom.xml 中配置 tomcat8-maven-plugin 并设置 settings.xml 中的 Tomcat 管理员凭据后,运行 mvn tomcat8:deploy (部署到外部 Tomcat) 或 mvn tomcat8:run (在嵌入式 Tomcat 中运行)。

  3. 访问应用: 部署成功后,在浏览器中访问 http://localhost:8080/web10/clock 即可看到动态时钟。

项目效果截图

动态时钟效果

动态时钟效果截图

遇到的问题与解决方案

在项目开发和部署过程中,我们遇到了一些常见的问题:

  1. Missing artifact jakarta.servlet.jsp:jakarta.servlet.jsp-api:jar:2.3.3

    • 问题: Maven 无法找到或下载 jakarta.servlet.jsp-api2.3.3 版本依赖。这通常是由于本地仓库缓存问题或远程仓库同步延迟导致。

    • 解决方案:

      • 首先尝试运行 mvn clean install -U 强制更新依赖。

      • 如果无效,将 pom.xmljakarta.servlet.jsp.version 的版本号更新到更稳定和常用的版本,例如 3.0.0

  2. ClassFormatException: Invalid byte tag in constant pool: 19 (Tomcat 版本与依赖不兼容):

    • 问题: 当使用 tomcat7-maven-plugin (对应 Tomcat 7) 运行项目时,Tomcat 无法处理 jakarta.xml.bind-api 等较新 Jakarta EE 依赖中包含的 module-info.class 文件。这表明 Tomcat 7 的内部类加载器与这些新特性不兼容。

    • 解决方案:pom.xml 中的 tomcat7-maven-plugin 替换为 tomcat8-maven-plugin 并更新到兼容的版本(例如 3.2.2)。Tomcat 8.5+ 对 Java 8 和 Jakarta EE 8 的兼容性更好。

  3. HTTP Status 404 - Not Found (直接访问 WEB-INF 目录下的 JSP):

    • 问题: 尝试直接在浏览器中访问 http://localhost:8080/web10/WEB-INF/views/clock.jsp 时,Tomcat 返回 404 错误。

    • 解决方案: 这是 Java Web 应用程序的预期安全行为。WEB-INF 目录是受保护的,其中的资源不能被客户端直接访问。正确的访问方式是通过 Spring MVC 控制器映射的 URL,即 http://localhost:8080/web10/clockDispatcherServlet 会在服务器内部将请求转发到 WEB-INF 下的 JSP 视图。

总结

通过本次动态时钟 Web 应用的开发,我不仅实践了 Spring MVC 框架的基本配置和使用,更深入理解了其背后的 MVC 设计模式原理。从请求的拦截、分发到视图的渲染,Spring MVC 提供了一套清晰且高效的机制来构建可维护、可扩展的 Web 应用程序。同时,解决实际开发中遇到的依赖冲突和部署问题,也进一步加深了对 Maven、Tomcat 和 Java Web 规范的理解。

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

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

相关文章

知行之桥如何将消息推送到钉钉群?

在钉钉平台中&#xff0c;机器人主要分为企业机器人和自定义机器人两类。本文将重点介绍如何通过自定义机器人&#xff0c;实现将知行之桥 EDI 系统的通知消息高效推送至钉钉群&#xff0c;帮助企业第一时间掌握业务动态。 一、在钉钉群中添加自定义机器人 在需要接收知行之桥…

哈工大计算机系统2024大作业——Hello的程序人生

计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 人工智能 学   号 2022112040 班 级 2203601 学 生 郄东昕 指 导 教 师 吴锐 计算机科学与技术学院…

联软SDP+安渡:收敛暴露面 从生产网自动取数 安全高效

制造业作为国家经济的基石&#xff0c;其网络安全面临着独特的挑战。出于合规和安全考虑&#xff0c;企业内部往往划分出多个相互隔离的网络区域&#xff0c;如办公网、研发网等&#xff0c;以提升整体安全防护能力。然而&#xff0c;网络隔离在保障安全的同时&#xff0c;也带…

LeetCode 543 二叉树的直径

二叉树的直径&#xff1a;树中任意两个节点间最长路径的长度。这个路径可能经过根节点&#xff0c;也可能不经过。 算法思路 采用深度优先搜索(DFS)的后序遍历方式&#xff0c;计算每个节点的左右子树高度&#xff0c;并在过程中更新最大直径。 代码解析 var diameterOfBin…

构建安全与合规的Jenkins环境:全周期审计方案详解

引言 Jenkins作为最流行的CI/CD工具之一&#xff0c;承载着企业核心的自动化构建与交付流程。然而&#xff0c;随着其复杂性的增加&#xff0c;安全漏洞、权限滥用和合规风险也随之而来。近期频发的供应链攻击&#xff08;如通过恶意插件入侵&#xff09;更是敲响警钟。如何确…

PowerShell Install Sql Server 2025 beta

Sql Server 2025 Download 其它版本和系统自动化脚本下载SQL Server 2025SSMS sql命令行安装ssms 命令行安装网盘分享SQL2025 beta

【K8S】K8S基础概念

一、 K8S组件 1.1 控制平面组件 kube-apiserver&#xff1a;公开 Kubernetes HTTP API 的核心组件服务器。 etcd&#xff1a;具备一致性和高可用性的键值存储&#xff0c;用于所有 API 服务器的数据存储。 kube-scheduler&#xff1a;查找尚未绑定到节点的 Pod&#xff0c;并将…

【C/C++】设计模式之工厂模式:从简单到抽象的演进

文章目录 设计模式之工厂模式&#xff1a;从简单到抽象的演进1 “工厂”模式分类1.1 简单工厂&#xff08;Simple Factory&#xff09;1.2 工厂方法&#xff08;Factory Method&#xff09;1.3 抽象工厂&#xff08;Abstract Factory&#xff09; 2 分析3 总结对比 设计模式之工…

HTTP 与 HTTPS 深度解析:原理、实践与大型项目应用

1. HTTP 与 HTTPS 基础概念 1.1 HTTP&#xff08;超文本传输协议&#xff09; 定义&#xff1a;应用层协议&#xff0c;基于 TCP/IP 通信&#xff0c;默认端口 80 特点&#xff1a; 无状态协议&#xff08;需 Cookie/Session 维护状态&#xff09; 明文传输&#xff08;易被…

【Excel 扩展正则的能力】工作中赋予处理单元格文本的强大正则表达提取能力

文本提取处理领域&#xff0c;正则表达式是最为强大的存在&#xff0c;工作中Excel 是常用的小型数据采集&#xff0c;处理&#xff0c;分析的工具但本身不具备正则的能力&#xff0c;让Excel拥有正则的能力无疑是如虎添翼的能力。 方案 让正则作为函数内容的一部分&#xff0c…

rabbitmq 使用过程中遇到的问题

1. 连接rabbitmq 地址写法&#xff0c;5672 是连接的端口号&#xff0c;15672是页面访问的端口号 2. elasticsearch 的访问端口是9200&#xff0c; 不是9300&#xff0c;9300 是后台通信端口号 &#xff0c;这个页面访问的端口号是一样&#xff0c; 3. rabbitmq 的5种交换接…

HTML实战:响应式个人资料页面

我将创建一个现代化的响应式个人资料页面,展示HTML在实际应用中的强大功能。这个页面将包含多个实战元素:导航栏、个人简介、技能展示、作品集和联系表单。 设计思路 使用Flexbox和Grid布局实现响应式设计 添加CSS过渡效果增强交互体验 实现深色/浅色模式切换功能 创建悬停动…

工业自动化实战:基于 VisionPro 与 C# 的机器视觉 PLC 集成方案

一、背景介绍 在智能制造领域&#xff0c;机器视觉检测与 PLC 控制的无缝集成是实现自动化生产线闭环控制的关键。本文将详细介绍如何使用 C# 开发上位机系统&#xff0c;实现 Cognex VisionPro 视觉系统与西门子 S7 PLC 的数据交互&#xff0c;打造高效、稳定的工业检测方案。…

如何处理 Python 入门难以进步的现象

Python 初学者难以进步的根本原因在于&#xff1a;缺乏项目实践、学习路径不清晰、没有掌握编程思维、忽略调试与源码阅读、缺乏系统性目标驱动。其中&#xff0c;“没有项目驱动导致学习孤岛效应”最为常见且致命。许多初学者只停留在语法知识、刷题阶段&#xff0c;无法构建可…

【后端高阶面经:缓存篇】37、高并发系统缓存性能优化:从本地到分布式的全链路设计

一、缓存性能优化的核心价值与分层架构 (一)缓存的多维价值体系 延迟优化 内存访问速度(100ns) vs 磁盘数据库(10ms+),性能提升10万倍+案例:电商详情页通过缓存将响应时间从500ms降至50ms吞吐提升 单机Redis可支撑10万QPS,分担数据库压力案例:秒杀系统通过缓存拦截9…

windows本地虚拟机上运行docker-compose案例

1、先构建镜像文件dockerfile&#xff0c;使用docker build -t redis-demo:1.0 -f dockerfile .来构建: FROM openjdk:8-jdk-alpineMAINTAINER qini<nqqq.com>VOLUME /data/upload_filesWORKDIR /usr/local/nqADD ./redis-demo.jar app.jarENV profile prod ENV timezon…

WPF布局基础

开头存一个快速排版插件 使用 XAML 格式化工具:XAML Styler - dino.c - 博客园 快捷键 在 Visual Studio 2022 中,输入类似 <Button ... /> 的自闭合 XAML 标签时,可以通过以下方式快速生成结尾的 />: 方法 1:输入 / 自动补全 输入标签名和属性: 输入 <B…

Electron 桌面程序读取dll动态库

序幕&#xff1a;被GFW狙击的第一次构建 当我在工位上输入npm install electron时&#xff0c;控制台跳出的红色警报如同数字柏林墙上的一道弹痕&#xff1a; Error: connect ETIMEDOUT 104.20.22.46:443 网络问题不用愁&#xff0c;请移步我的另外文章进行配置&#xff1a;…

javascript中运算符的优先级

优先级运算类型关联性运算符19圆括号n/a( … )18成员访问从左到右… . …Computed Member Access从左到右… [ … ]new (带参数列表)n/anew … ( … )17函数调用从左到右… ( … )new (无参数列表)从右到左new …16后置递增(运算符在后)n/a… 后置递减(运算符在后)n/a… –15逻…

Linux的交换区

Linux 交换区&#xff08;Swap&#xff09;详解 交换区&#xff08;Swap&#xff09;是 Linux 系统用于扩展内存的一种机制&#xff0c;它将部分磁盘空间虚拟成内存使用。当物理内存&#xff08;RAM&#xff09;不足时&#xff0c;系统会将不活跃的内存页移动到交换区&#xf…