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

news2024/11/26 12:18:30

文章目录

        • 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/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/mvc
                           http://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 {

    @Bean
    public 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.java

src/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 {

    @Autowired
    private 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.coloradmin.cn/o/2247835.html

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

相关文章

使用 OpenCV 进行视频中的行人检测

在计算机视觉领域&#xff0c;行人检测是一个重要的研究方向&#xff0c;它在视频监控、自动驾驶、人机交互等领域都有着广泛的应用。本文将介绍如何使用 OpenCV 库来实现视频中的行人检测。 环境准备 首先&#xff0c;我们需要安装 OpenCV 库。可以通过以下命令来安装&#…

【K8s】专题十五(4):Kubernetes 网络之 Calico 插件安装、切换网络模式、卸载

本文内容均来自个人笔记并重新梳理&#xff0c;如有错误欢迎指正&#xff01; 如果对您有帮助&#xff0c;烦请点赞、关注、转发、订阅专栏&#xff01; 专栏订阅入口 | 精选文章 | Kubernetes | Docker | Linux | 羊毛资源 | 工具推荐 | 往期精彩文章 【Docker】&#xff08;全…

鸿蒙面试题-某迈-2024年11月22日

某迈-2024年11月22日 1. 自我介绍 2. 鸿蒙中地图功能如何实现&#xff0c;申请流程是什么样的 主要通过 集成 Map Kit 的功能来实现Map Kit 功能很强大&#xff0c;比如有 创建地图&#xff1a;呈现内容包括建筑、道路、水系等。地图交互&#xff1a;控制地图的交互手势和交…

微软要求 Windows Insider 用户试用备受争议的召回功能

拥有搭载 Qualcomm Snapdragon 处理器的 Copilot PC 的 Windows Insider 计划参与者现在可以试用 Recall&#xff0c;这是一项臭名昭著的快照拍摄 AI 功能&#xff0c;在今年早些时候推出时受到了很多批评。 Windows 营销高级总监 Melissa Grant 上周表示&#xff1a;“我们听…

【Android】静态广播接收不到问题分析思路

参考资料&#xff1a; Android 静态广播注册流程(广播2)-CSDN博客 Android广播发送流程(广播3)_android 发送广播-CSDN博客 https://zhuanlan.zhihu.com/p/347227068 在Android中&#xff0c;静态广播如果静态广播不能接收&#xff0c;我们可以从整个流程中去分析&#xff…

非递归遍历二叉树(数据结构)

我的博客主页 非递归遍历二叉树 前序遍历&#xff08;迭代&#xff09;中序遍历&#xff08;迭代&#xff09;后续遍历&#xff08;迭代&#xff09; 二叉树的遍历方式有&#xff1a;前序遍历、中序遍历、后续遍历&#xff0c;层序遍历&#xff0c;而树的大部分情况下都是通过递…

2024 java大厂面试复习总结(一)(持续更新)

10年java程序员&#xff0c;2024年正好35岁&#xff0c;2024年11月公司裁员&#xff0c;记录自己找工作时候复习的一些要点。 java基础 hashCode()与equals()的相关规定 如果两个对象相等&#xff0c;则hashcode一定也是相同的两个对象相等&#xff0c;对两个对象分别调用eq…

【可变参数,lambda,function,bind】

可变参数 Args模板参数包 解析参数包&#xff0c;使用递归和再来一个参数包。参数包传参时&#xff0c;会把第一个数据给前面的&#xff0c;剩下的数据全部传给后面的参数包&#xff0c;参数包就一直变小。 lambda表达式 书写格式&#xff1a;[capture-list] (parameters)…

ArcGIS API for Javascript学习

一、ArcGIS API for Javascript 介绍 ArcGIS API for Javascript 是由美国 Esri 公司推出&#xff0c;跟随ArcGIS 9.3 同时发布的&#xff0c;是Esri 基于dojo 框架和 REST 风格实现的一套编程接口。通过 ArcGIS API for Javascript可以对ArcGIS for Server 进行访问&#xff…

JavaScript的let、var、const

这张图片主要介绍了JavaScript中的三种变量声明方式&#xff1a;let、var和const。 1. let 含义&#xff1a;let是现在实际开发中常用的变量声明方式。特点&#xff1a; 块级作用域&#xff1a;let声明的变量只在其所在的块级作用域内有效。例如&#xff1a;{let x 10; } co…

24.11.25 Mybatis1

1.Mybatis介绍 1.封装JDBC 减少重复性代码 2.ORM(实体关系映射框架) 通过框架 实体类 <--> 数据表 自动封装对象 3.半自动的ORM框架 还需要写sql语句 2.使用mybatis连接数据库(调通一遍 记住需要哪些文件) 1.创建全局配置文件 mybatis-config.xml <?xml ver…

【Python爬虫五十个小案例】爬取猫眼电影Top100

博客主页&#xff1a;小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介&#xff1a;分享五十个Python爬虫小案例 &#x1f40d;引言 猫眼电影是国内知名的电影票务与资讯平台&#xff0c;其中Top100榜单是影迷和电影产业观察者关注的重点。通过爬取猫眼电影Top10…

Oh-My-ZSH安装教程

1. 安装zsh sudo apt-get install zsh2.安装on-my-zsh wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh上面方式很大可能因为网络连接问题而失败&#xff0c;可以通过以下方式&#xff1a; git clone gitgithub.com:ohmyzsh/ohmyzsh…

三六零[601360]行情数据接口

1、三六零&#xff1a;实时行情 Restful API # 测试接口&#xff1a;可以复制到浏览器打开 https://tsanghi.com/api/fin/stock/XSHG/realtime?tokendemo&ticker601360获取股票实时行情&#xff08;开、高、低、收、量&#xff09;。 请求方式&#xff1a;GET。 Python示例…

用 OceanBase 4.3.3,搭建《黑神话:悟空》的专属游戏AI助手

本文分享了如何基于 OceanBase 4.3.3 bp1 社区版的向量检索能力&#xff0c;通过几条简单的命令&#xff0c;快速搭建一个定制化的专属游戏助手的过程。 背景 在 OceanBase 最新推出 V 4.3.3 免费试用的同时&#xff0c;也同时发布了几个基于OB Cloud 的向量能力&#xff0c;搭…

tableau练习-制作30个图表

一、导入数据 1、导入数据 -添加-添加连接-到文件-excel格式用第一个excel导入&#xff0c;csv格式用第二个文本格式导入 2、连接数据 -从旁边这里直接拖到中间 标头连接 -日期若不一致需调节日期格式 3、保存数据 点击数据提取-再保存数据&#xff0c;保存为twbx格式 二、设计…

QT QHorizontalSpacer控件 全面详解

本系列文章全面的介绍了QT中的57种控件的使用方法以及示例,包括 Button(PushButton、toolButton、radioButton、checkBox、commandLinkButton、buttonBox)、Layouts(verticalLayout、horizontalLayout、gridLayout、formLayout)、Spacers(verticalSpacer、horizontalSpacer)、…

第六届智能控制、测量与信号处理国际学术会议 (ICMSP 2024)

重要信息 2024年11月29日-12月1日 中国陕西西安石油大学雁塔校区 大会官网&#xff1a;www.icmsp.net 大会简介 第六届智能控制、测量与信号处理国际学术会议&#xff08;ICMSP 2024&#xff09;由西安石油大学、中海油田服务股份有限公司、浙江水利水电学院与中国石油装备…

Qt中2D绘制系统

目录 一、Qt绘制系统 1.1Qt绘制基本概念 1.2 绘制代码举例 1.3画家 1.3.1 QPainter的工作原理&#xff1a; 1.3.2 自定义绘制饼状图&#xff1a; 1.4画笔和画刷 1.4.1画笔 1.4.2 画刷填充样式 1.5 反走样和渐变 1.6绘制设备 1.7坐标变换 1.8QPainterPath 1.9绘制文…

Linux——Uboot命令使用

什么是Uboot&#xff1f; 1&#xff09;Uboot是一个裸机程序&#xff0c;比较复杂。类似我们PC机的BIOS程序。 2&#xff09;Uboot就是一个bootloader&#xff0c;作用就是用于启动Linux或者其他系统&#xff0c;Uboot最主要的工作是初始化DDR&#xff0c;因为Linux的运行是运行…