深入解析 Spring MVC:架构、组件与最佳实践

server/2024/12/3 3:13:58/

文章目录

        • 1. **DispatcherServlet**
        • 2. **HandlerMapping**
        • 3. **HandlerAdapter**
        • 4. **Controller**
        • 5. **ModelAndView**
        • 6. **ViewResolver**
        • 7. **View**
      • 工作流程
      • 配置方式
        • XML 配置
        • Java 配置
      • 最佳实践
      • 示例项目
        • 项目目录结构
        • 控制器 (`HelloWorldController.java`)
        • 服务层 (`HelloWorldService.java`)
        • 视图 (`hello.jsp`)
        • 配置文件 (`application.properties`)
        • 全局异常处理 (`GlobalExceptionHandler.java`)

1. DispatcherServlet

DispatcherServlet 是 Spring MVC 的前端控制器,它负责接收所有的 HTTP 请求,并将请求分发到相应的处理器。它是整个 Spring MVC 框架的核心组件。

  • 初始化DispatcherServlet 在启动时会初始化一系列的组件,如 HandlerMappingHandlerAdapterViewResolver 等。
  • 请求处理:接收到请求后,DispatcherServlet 会通过 HandlerMapping 找到合适的处理器,然后通过 HandlerAdapter 调用处理器方法。
2. HandlerMapping

HandlerMapping 负责将请求映射到处理器。Spring MVC 提供了多种 HandlerMapping 实现,包括:

  • RequestMappingHandlerMapping:基于 @RequestMapping 注解进行请求映射。
  • BeanNameUrlHandlerMapping:基于 Bean 名称进行请求映射。
  • SimpleUrlHandlerMapping:基于 URL 模式进行请求映射。
3. HandlerAdapter

HandlerAdapter 负责调用处理器方法。Spring MVC 提供了多种 HandlerAdapter 实现,包括:

  • RequestMappingHandlerAdapter:支持基于 @RequestMapping 注解的方法调用。
  • HttpRequestHandlerAdapter:支持 HttpRequestHandler 接口的方法调用。
4. Controller

控制器是处理请求的主要组件。在 Spring MVC 中,控制器类通常使用 @Controller 注解标记,并且方法上使用 @RequestMapping 或其派生注解(如 @GetMapping, @PostMapping)来指定处理哪些请求。

5. ModelAndView

ModelAndView 对象用于封装模型数据和视图信息。控制器方法可以返回 ModelAndView 对象,其中包含模型数据和视图名称。

6. ViewResolver

视图解析器负责将逻辑视图名称解析为具体的视图对象。常用的视图解析器有:

  • InternalResourceViewResolver:用于 JSP 视图。
  • ThymeleafViewResolver:用于 Thymeleaf 视图。
  • FreeMarkerViewResolver:用于 FreeMarker 视图。
7. View

视图负责渲染最终的页面,展示给用户。视图可以是 JSP、FreeMarker、Thymeleaf 等模板引擎生成的页面。

工作流程

  1. 客户端发送请求:客户端(如浏览器)发送 HTTP 请求到服务器。
  2. 请求到达 DispatcherServlet:请求被 DispatcherServlet 捕获。
  3. HandlerMapping 定位处理器DispatcherServlet 使用 HandlerMapping 查找处理请求的控制器方法。
  4. HandlerAdapter 调用处理器DispatcherServlet 使用 HandlerAdapter 调用控制器方法。
  5. 控制器处理请求:控制器方法处理请求,返回 ModelAndView 对象。
  6. ViewResolver 解析视图DispatcherServlet 使用 ViewResolver 将逻辑视图名称解析为具体的视图对象。
  7. 视图渲染:视图对象渲染最终的页面,并返回给客户端。

配置方式

XML 配置

传统的 Spring MVC 配置通常是通过 XML 文件完成的。以下是一个简单的 XML 配置示例:

<!-- web.xml -->
<servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping><!-- dispatcher-servlet.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 扫描 Controller --><context:component-scan base-package="com.example.controller" /><!-- 启用 MVC 注解驱动 --><mvc:annotation-driven /><!-- 视图解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/" /><property name="suffix" value=".jsp" /></bean>
</beans>
Java 配置

现代的 Spring MVC 项目通常使用 Java 配置。以下是一个简单的 Java 配置示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;@Configuration
@ComponentScan(basePackages = "com.example.controller")
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {@Beanpublic InternalResourceViewResolver viewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix("/WEB-INF/views/");resolver.setSuffix(".jsp");return resolver;}
}

最佳实践

  1. 分层设计:将应用分为控制器层、服务层和数据访问层,保持各层职责清晰。
  2. 异常处理:使用 @ControllerAdvice@ExceptionHandler 注解来集中处理异常。
  3. 数据验证:使用 JSR-303 标准的数据验证框架(如 Hibernate Validator)来验证请求参数。
  4. 国际化:使用 Spring 的国际化支持来提供多语言界面。
  5. 安全性:使用 Spring Security 来保护应用的安全性。
  6. 性能优化:合理使用缓存、异步处理等技术来提升应用性能。

示例项目

假设我们有一个简单的 Spring Boot 项目,使用 Spring MVC 构建一个基本的 Web 应用程序。

项目目录结构
src/main/java
│── com.example
│   └── controller
│       └── HelloWorldController.java
│── com.example.service
│   └── HelloWorldService.java
│── com.example.repository
│   └── HelloWorldRepository.java
└── Application.javasrc/main/resources
│── static
│── templates
│── application.properties
控制器 (HelloWorldController.java)
package com.example.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.service.HelloWorldService;@Controller
public class HelloWorldController {@Autowiredprivate HelloWorldService helloWorldService;@GetMapping("/hello")public String hello(Model model) {String message = helloWorldService.getMessage();model.addAttribute("message", message);return "hello"; // 返回视图名称}
}
服务层 (HelloWorldService.java)
package com.example.service;import org.springframework.stereotype.Service;@Service
public class HelloWorldService {public String getMessage() {return "Hello, Spring MVC!";}
}
视图 (hello.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Hello World</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>
配置文件 (application.properties)
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
全局异常处理 (GlobalExceptionHandler.java)
package com.example.controller;import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public ModelAndView handleException(Exception ex) {ModelAndView modelAndView = new ModelAndView("error");modelAndView.addObject("errorMessage", ex.getMessage());return modelAndView;}
}

http://www.ppmy.cn/server/146910.html

相关文章

mysql系列2—InnoDB数据存储方式

背景 本文将深入探讨InnoDB的底层存储机制&#xff0c;包括行格式、页结构、页目录以及表空间等核心概念。通过全面了解这些基础概念&#xff0c;有助于把握MySQL的存储架构&#xff0c;也为后续深入讨论MySQL的索引原理和查询优化策略奠定了基础。 1.行格式 mysql中数据以行…

小车AI视觉交互--2.颜色跟随

一、实验目标 前面利用了颜色对象在摄像头画面的x&#xff0c;y不同位置通过云台进行跟踪&#xff0c;接下来我们可以在这个基础上修改下&#xff0c;x方向改为车身左右运动进行跟随&#xff0c;然后根据识别的图像外切圆大小进行前进的控制&#xff0c;通过二者叠加来整体控制…

使用1panel一键安装Ollama WebUI连接本地Ollama使用开源ai模型

当前我的环境 设备有限只有一张3060 12gb显卡&#xff0c;平时用来轻度学习 主机&#xff1a;windows server Ollama&#xff1a;windows版&#xff08;它也有linux和mac&#xff09; 因虚拟机使用的服务器无显卡&#xff0c;只用来跑面板和WebUi 虚拟机&#xff1a;ubuntu se…

云原生周刊:K8s 严重漏洞

云原生周刊&#xff1a;K8s 严重漏洞 开源项目推荐 KitOps KitOps 是一款开源的 DevOps 工具&#xff0c;专为 AI/ML 项目的全生命周期管理而设计&#xff0c;通过将模型、数据集、代码和配置打包并版本化为符合 OCI&#xff08;开放容器标准&#xff09;的工件&#xff0c;…

Redis双活切换平台建设

背景 随着公司目前整体双活能力的建设完成&#xff0c;需要对Redis组件的双活能力进行演练和验证。但在实际生产环境中&#xff0c;面对如此大规模的Redis集群&#xff0c;演练过程中几个关键问题仍然存在&#xff1a;主从切换时间长、系统高可用要求高、运维流程复杂&#xf…

贝叶斯统计:高斯分布均值μ的后验分布推导

使用贝叶斯统计方法 均值 ( μ \mu μ ) 的后验分布解析 在贝叶斯统计中&#xff0c;后验分布表示在观察到数据后&#xff0c;对参数的更新后的信念。本篇文章将结合高斯分布的假设&#xff0c;详细解析均值 ( μ \mu μ ) 的后验分布推导过程&#xff0c;并对 ( μ \mu μ…

【2024】前端学习笔记19-ref和reactive使用

学习笔记 1.ref2.reactive3.总结 1.ref ref是 Vue 3 中用来创建响应式引用的一个函数&#xff0c;通常用于基本数据类型&#xff08;如字符串、数字、布尔值等&#xff09;或对象/数组的单一值。 ref特点&#xff1a; ref 可以用来创建单个响应式对象对于 ref 包裹的值&…

Jenkins-基于 JNLP协议的 Java Web 启动代理

在上一篇的基础配置上进行以下步骤 工作流程&#xff1a; 通过 JNLP 启动代理&#xff0c;客户端从 Jenkins 服务器上下载一个 agent.jar 文件。该文件启动时&#xff0c;代理程序通过 JNLP 协议连接到 Jenkins 主节点。一旦连接成功&#xff0c;代理节点就可以执行从主节点分…