SpringMVC学习笔记一: SpringMVC原理及实例解析
在Java Web开发领域,SpringMVC(Spring Web MVC)作为Spring框架的核心模块之一,是构建灵活、高效的Web应用程序的主流选择。它基于MVC(Model-View-Controller)设计模式,通过分离关注点(数据、展示、控制逻辑),简化了Web应用的开发流程,提升了代码的可维护性和扩展性。
本文作为SpringMVC学习笔记的第一篇,将从核心原理和实战案例两方面展开,帮助读者深入理解SpringMVC的工作机制,并通过一个完整的示例掌握其基本使用方法。无论你是Java Web初学者,还是希望系统梳理SpringMVC知识的开发者,本文都能为你提供清晰的学习路径。
目录#
1. 什么是SpringMVC?#
SpringMVC是Spring框架提供的Web层解决方案,它基于Servlet API实现,用于处理HTTP请求并构建Web应用。其核心目标是通过MVC模式将业务逻辑、数据展示和用户交互分离,降低代码耦合度。
核心特性:#
- 松耦合设计:通过依赖注入(DI)和控制反转(IoC)管理组件,减少硬编码依赖。
- 灵活的URL映射:支持注解式请求映射,简化URL与控制器方法的绑定。
- 强大的数据绑定:自动将请求参数绑定到Java对象,支持类型转换。
- 内置视图解析:支持JSP、Thymeleaf、FreeMarker等多种视图技术。
- 可扩展的拦截器:通过拦截器实现权限控制、日志记录等横切功能。
- 与Spring生态无缝集成:可直接使用Spring的事务管理、AOP等功能。
2. MVC设计模式回顾#
在深入SpringMVC之前,先回顾MVC设计模式的核心思想:将应用分为三个核心模块,各司其职。
- Model(模型):封装应用数据和业务逻辑,通常对应JavaBean或领域模型。
- View(视图):负责数据展示,如JSP、HTML页面,不包含业务逻辑。
- Controller(控制器):接收用户请求,调用模型处理业务,返回结果给视图。
MVC的优势在于职责分离:模型专注于数据和业务,视图专注于展示,控制器专注于流程控制,避免代码混杂。
3. SpringMVC核心组件解析#
SpringMVC的核心是通过一系列组件协同工作,完成请求处理和响应。以下是关键组件及其作用:
3.1 DispatcherServlet(前端控制器)#
- 作用:整个SpringMVC的"中央调度器",接收所有HTTP请求,协调其他组件工作。
- 地位:相当于MVC中的"Controller"角色,但实际职责是分发请求,而非处理业务逻辑。
3.2 HandlerMapping(处理器映射器)#
- 作用:根据请求URL查找对应的Handler(处理器,即Controller中的方法)。
- 常见实现:
RequestMappingHandlerMapping(基于注解@RequestMapping映射)。
3.3 HandlerAdapter(处理器适配器)#
- 作用:根据Handler的类型(如注解式、XML配置式),调用对应的Handler方法。
- 常见实现:
RequestMappingHandlerAdapter(适配注解式Controller)。
3.4 Handler(处理器)#
- 作用:即业务控制器(Controller类中的方法),负责处理具体业务逻辑,返回
ModelAndView(模型数据+视图名)。
3.5 ModelAndView#
- 作用:封装处理结果,包含两部分:
Model:键值对形式的业务数据(如查询结果)。View:逻辑视图名(如"index"),需通过ViewResolver解析为物理视图。
3.6 ViewResolver(视图解析器)#
- 作用:将逻辑视图名解析为物理视图对象(如JSP路径)。
- 示例:
InternalResourceViewResolver(解析JSP视图,配置前缀/WEB-INF/views/和后缀.jsp)。
3.7 Interceptor(拦截器)#
- 作用:在请求处理的不同阶段(如请求前、请求后、视图渲染后)执行自定义逻辑,如登录验证、日志记录。
4. SpringMVC请求处理流程#
SpringMVC的请求处理流程可概括为以下步骤,结合组件协同工作:
- 用户发送请求:浏览器或客户端发送HTTP请求(如
http://localhost:8080/hello)。 - DispatcherServlet接收请求:所有请求被
DispatcherServlet拦截(通过web.xml配置映射)。 - HandlerMapping查找Handler:
DispatcherServlet调用HandlerMapping,根据URL找到对应的Handler(Controller方法)。 - HandlerAdapter执行Handler:
DispatcherServlet通过HandlerAdapter调用Handler方法,处理业务逻辑,返回ModelAndView。 - ViewResolver解析视图:
DispatcherServlet将ModelAndView中的逻辑视图名交给ViewResolver,解析为物理视图(如JSP路径)。 - 渲染视图并响应:视图对象(如JSP)结合
Model数据渲染页面,生成HTML响应给客户端。
流程图示意:
请求 → DispatcherServlet → HandlerMapping → Handler → HandlerAdapter → ModelAndView → ViewResolver → View → 响应
5. 实战案例:从零搭建SpringMVC应用#
下面通过一个"Hello World"示例,演示SpringMVC的基本使用。
5.1 环境准备#
- 开发工具:IntelliJ IDEA
- 构建工具:Maven
- 服务器:Tomcat 9
- 依赖:SpringMVC、Servlet API、JSTL
5.2 步骤1:创建Maven Web项目#
- 新建Maven项目,选择
maven-archetype-webapp。 - 配置
pom.xml,添加核心依赖:
<dependencies>
<!-- SpringMVC核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.20</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- JSTL(用于JSP页面) -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
</dependencies>5.3 步骤2:配置web.xml(注册DispatcherServlet)#
在src/main/webapp/WEB-INF/web.xml中配置DispatcherServlet:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置DispatcherServlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载SpringMVC配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!-- 启动时加载(优先级1) -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 映射所有请求(/表示除.jsp外的所有请求) -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>5.4 步骤3:创建SpringMVC配置文件#
在src/main/resources下创建springmvc-servlet.xml,配置组件扫描和视图解析器:
<?xml version="1.0" encoding="UTF-8"?>
<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"/>
<!-- 启用SpringMVC注解驱动(支持@RequestMapping等注解) -->
<mvc:annotation-driven/>
<!-- 视图解析器:解析JSP视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀:JSP文件所在目录 -->
<property name="prefix" value="/WEB-INF/views/"/>
<!-- 后缀:JSP文件扩展名 -->
<property name="suffix" value=".jsp"/>
</bean>
</beans>5.5 步骤4:创建Controller#
在com.example.controller包下创建HelloController:
package com.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller // 标记为控制器组件
public class HelloController {
// 映射请求URL:/hello
@RequestMapping("/hello")
public String hello(Model model) {
// 向模型中添加数据(键值对)
model.addAttribute("message", "Hello, SpringMVC!");
// 返回逻辑视图名(由视图解析器解析为 /WEB-INF/views/hello.jsp)
return "hello";
}
}5.6 步骤5:创建JSP视图#
在src/main/webapp/WEB-INF/views目录下创建hello.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SpringMVC Hello</title>
</head>
<body>
<h1>${message}</h1> <!-- 从Model中获取数据 -->
</body>
</html>5.7 步骤6:部署与测试#
- 配置Tomcat服务器,将项目部署到Tomcat。
- 启动Tomcat,访问
http://localhost:8080/项目名/hello。 - 页面显示
Hello, SpringMVC!,表示成功。
6. 常见实践与最佳实践#
6.1 注解使用规范#
- @Controller vs @RestController:
@Controller:返回逻辑视图名,需配合视图解析器渲染页面。@RestController:等价于@Controller + @ResponseBody,直接返回数据(JSON/XML),适用于RESTful API。
- 请求映射注解:优先使用
@GetMapping、@PostMapping等细分注解(替代@RequestMapping(method = RequestMethod.GET)),语义更清晰。
6.2 控制器设计原则#
- 保持控制器简洁:控制器仅负责接收请求、调用业务层、返回结果,不包含复杂业务逻辑(业务逻辑交给Service层)。
- 参数绑定:使用
@RequestParam接收URL参数,@PathVariable接收路径变量(如/user/{id}),@ModelAttribute绑定表单数据到JavaBean。
6.3 视图解析与静态资源处理#
- 静态资源(CSS/JS/图片):默认
DispatcherServlet会拦截所有请求,导致静态资源无法访问。需在Spring配置中添加:<mvc:default-servlet-handler/> <!-- 让默认Servlet处理静态资源 --> - 视图技术选择:JSP适用于简单页面,复杂场景推荐Thymeleaf(无依赖Servlet容器,支持HTML原型)。
6.4 异常处理#
- 使用
@ExceptionHandler注解在Controller中定义异常处理方法,或通过@ControllerAdvice全局捕获异常,避免页面直接显示错误堆栈。
6.5 输入验证#
- 使用JSR-303注解(如
@NotNull、@Size)配合@Valid对请求参数进行校验,提升数据安全性。
7. 总结#
本文从SpringMVC的核心概念、工作原理出发,通过一个完整的"Hello World"示例,展示了SpringMVC的基本使用流程。关键要点包括:
- SpringMVC基于MVC模式,通过DispatcherServlet协调各组件完成请求处理。
- 核心组件包括HandlerMapping、HandlerAdapter、ViewResolver等,需理解其协同流程。
- 实战中需注意配置文件(web.xml、Spring配置)、控制器注解、视图解析等细节。
后续学习可深入SpringMVC的高级特性,如拦截器、数据绑定、RESTful API设计等。
8. 参考资料#
- Spring官方文档 - Spring Web MVC
- 《Spring实战(第5版)》- Craig Walls
- SpringMVC教程 - Runoob
- IntelliJ IDEA + Maven + Tomcat搭建SpringMVC项目