深入解析:SpringMVC 学习指南:从入门到实战

深入解析:SpringMVC 学习指南:从入门到实战

文章目录一、SpringMVC 基础认知1.1 什么是 SpringMVC?1.2 MVC 设计模式1.3 SpringMVC 的优势二、环境搭建与入门案例2.1 开发环境准备2.2 Maven 核心依赖2.3 核心配置文件2.3.1 Web 配置(web.xml)2.3.2 SpringMVC 配置(spring-mvc.xml)2.4 入门案例:第一个 SpringMVC 程序2.4.1 创建 Controller2.4.2 创建视图(hello.jsp)2.4.3 运行测试三、SpringMVC 核心组件与工作流程3.1 核心组件3.2 请求处理流程四、请求映射与参数绑定4.1 请求映射注解4.2 参数绑定4.2.1 基本类型参数4.2.2 实体类参数4.2.3 数组与集合参数4.2.4 注解绑定参数五、视图技术与数据传递5.1 视图解析器配置5.1.2 Thymeleaf 视图解析器(推荐)5.2 数据传递方式六、文件上传与下载6.1 文件上传配置6.2 文件上传实现6.3 文件下载实现七、拦截器(Interceptor)7.1 自定义拦截器7.2 配置拦截器八、异常处理8.1 自定义异常类8.2 全局异常处理器九、RESTful 风格开发9.1 RESTful API 设计示例9.2 实现 RESTful Controller十、实战案例:用户管理系统10.1 功能设计10.2 代码实现(核心部分)10.2.1 Service 层10.2.2 Controller 层10.2.3 视图页面(user/list.jsp)十一、学习资源与进阶方向11.1 官方资源11.2 进阶学习方向

一、SpringMVC 基础认知1.1 什么是 SpringMVC?SpringMVC 是 Spring 提供的用于构建 Web 应用的 MVC 框架,它分离了 Web 应用的模型(Model)、视图(View)和控制器(Controller),通过一套注解简化了 Web 开发流程,实现了请求处理、参数绑定、视图渲染等核心功能。

1.2 MVC 设计模式MVC 是一种软件架构模式,将应用分为三个核心部分:

Model(模型):处理业务逻辑和数据(如 JavaBean、Service、DAO)View(视图):展示数据(如 JSP、HTML、Thymeleaf)Controller(控制器):接收请求、协调 Model 和 View(如 SpringMVC 的 Controller)SpringMVC 通过 DispatcherServlet(前端控制器)实现了 MVC 各组件的解耦,简化了请求处理流程。

1.3 SpringMVC 的优势与 Spring 框架无缝整合,共享 IOC 容器和 AOP 功能基于注解开发,配置简单,代码简洁灵活的参数绑定和视图解析强大的拦截器机制,便于实现权限控制、日志记录等功能支持 RESTful 风格 API 开发良好的扩展性,可集成各种视图技术和第三方框架二、环境搭建与入门案例2.1 开发环境准备JDK:1.8 及以上构建工具:Maven 3.6+Web 服务器:Tomcat 9.0+IDE:IntelliJ IDEA 或 Eclipse2.2 Maven 核心依赖在 pom.xml 中添加 SpringMVC 及相关依赖:

<

!-- SpringMVC 核心 -->

org.springframework

spring-webmvc

5.3.20

<

!-- Web 基础 -->

javax.servlet

javax.servlet-api

3.1.0

provided

<

!-- JSTL(可选,用于 JSP 视图) -->

javax.servlet.jsp.jstl

jstl-api

1.2

2.3 核心配置文件2.3.1 Web 配置(web.xml)配置前端控制器 DispatcherServlet 和编码过滤器:

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_3_1.xsd"

version="3.1">

<

!-- 配置前端控制器 DispatcherServlet -->

dispatcherServlet

org.springframework.web.servlet.DispatcherServlet

<

!-- 加载 SpringMVC 配置文件 -->

contextConfigLocation

classpath:spring-mvc.xml

<

!-- 启动时加载 -->

1

dispatcherServlet

/

<

!-- 拦截所有请求 -->

<

!-- 编码过滤器:解决中文乱码 -->

characterEncodingFilter

org.springframework.web.filter.CharacterEncodingFilter

encoding

UTF-8

forceEncoding

true

characterEncodingFilter

/*

2.3.2 SpringMVC 配置(spring-mvc.xml)配置包扫描、注解驱动、视图解析器等:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd">

<

!-- 扫描 Controller 包 -->

<

!-- 开启注解驱动:支持 @RequestMapping 等注解 -->

<

!-- 静态资源放行 -->

<

!-- 视图解析器(JSP) -->

<

!-- 视图前缀 -->

<

!-- 视图后缀 -->

2.4 入门案例:第一个 SpringMVC 程序2.4.1 创建 Controller

package com.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller // 标记为控制器

public class HelloController {

// 映射请求路径:http://localhost:8080/hello

@RequestMapping("/hello")

public String hello(Model model) {

// 向模型中添加数据

model.addAttribute("message", "Hello, SpringMVC!");

// 返回视图名(将被解析为 /WEB-INF/jsp/hello.jsp)

return "hello";

}

}

2.4.2 创建视图(hello.jsp)在 WEB-INF/jsp/ 目录下创建 hello.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

SpringMVC 入门

${message}

<

!-- 显示模型中的数据 -->

2.4.3 运行测试将项目部署到 Tomcat访问地址:http://localhost:8080/hello页面将显示:Hello, SpringMVC!三、SpringMVC 核心组件与工作流程3.1 核心组件DispatcherServlet:前端控制器,接收所有请求并协调其他组件HandlerMapping:处理器映射,根据请求路径查找对应的 Controller 方法HandlerAdapter:处理器适配器,调用 Controller 方法并适配参数Controller:处理器,处理具体业务逻辑ModelAndView:封装处理结果(模型数据和视图名)ViewResolver:视图解析器,将视图名解析为具体视图(如 JSP)View:视图,渲染模型数据并展示给用户3.2 请求处理流程1.客户端发送请求到 DispatcherServlet 2.DispatcherServlet 调用 HandlerMapping 查找处理该请求的 Controller 方法 3.HandlerMapping 返回处理器执行链(包含 Controller 和拦截器) 4.DispatcherServlet 调用 HandlerAdapter 适配并执行 Controller 方法 5.Controller 方法处理业务逻辑,返回 ModelAndView 6.DispatcherServlet 调用 ViewResolver 解析视图名 7.ViewResolver 返回具体 View 对象 8.DispatcherServlet 调用 View 的渲染方法,将模型数据填充到视图 9.响应结果返回给客户端

四、请求映射与参数绑定4.1 请求映射注解SpringMVC 通过注解映射请求路径,常用注解: 示例:复杂请求映射

@Controller

@RequestMapping("/user") // 类级别映射:所有方法路径前缀为 /user

public class UserController {

// 完整路径:/user/list(仅接受 GET 请求)

@GetMapping("/list")

public String list() {

return "user/list";

}

// 完整路径:/user/add(仅接受 POST 请求)

@PostMapping("/add")

public String add() {

return "redirect:/user/list"; // 重定向

}

}

4.2 参数绑定SpringMVC 支持多种参数绑定方式,自动将请求参数转换为方法参数。

4.2.1 基本类型参数

// 请求路径:/user/detail?id=1&

name=zhangsan

@GetMapping("/detail")

public String detail(Integer id, String name, Model model) {

model.addAttribute("id", id);

model.addAttribute("name", name);

return "user/detail";

}

4.2.2 实体类参数创建实体类 User:

public class User {

private Integer id;

private String username;

private Integer age;

// getter/setter

}

绑定实体类参数:

// 请求路径:/user/save?username=zhangsan&

age=20

@PostMapping("/save")

public String save(User user) {

// 直接使用 user 对象

System.out.println(user.getUsername() + " - " + user.getAge());

return "redirect:/user/list";

}

4.2.3 数组与集合参数

// 请求路径:/user/delete?ids=1&

ids=2&

ids=3

@GetMapping("/delete")

public String delete(Integer[] ids) {

for (Integer id : ids) {

System.out.println("删除:" + id);

}

return "redirect:/user/list";

}

4.2.4 注解绑定参数@RequestParam:指定请求参数名@PathVariable:绑定 URL 路径变量@RequestHeader:获取请求头信息@CookieValue:获取 Cookie 值

// @RequestParam 示例

@GetMapping("/search")

public String search(

@RequestParam(value = "keyword", required = false, defaultValue = "") String keyword) {

System.out.println("搜索关键词:" + keyword);

return "search";

}

// @PathVariable 示例(RESTful 风格)

@GetMapping("/user/{id}")

public String getById(@PathVariable Integer id) {

System.out.println("用户 ID:" + id);

return "user/detail";

}

五、视图技术与数据传递5.1 视图解析器配置SpringMVC 支持多种视图技术,通过 ViewResolver 配置:

5.1.2 Thymeleaf 视图解析器(推荐)添加依赖:

org.thymeleaf

thymeleaf-spring5

3.0.15.RELEASE

配置解析器:

5.2 数据传递方式向视图传递数据的三种常用方式: Model 接口:

@RequestMapping("/list")

public String list(Model model) {

model.addAttribute("users", userService.findAll()); // 添加数据

return "user/list";

}

ModelAndView:

@RequestMapping("/list")

public ModelAndView list() {

ModelAndView mav = new ModelAndView();

mav.addObject("users", userService.findAll()); // 添加数据

mav.setViewName("user/list"); // 设置视图名

return mav;

}

Map 集合:

@RequestMapping("/list")

public String list(Map map) {

map.put("users", userService.findAll()); // 添加数据

return "user/list";

}

六、文件上传与下载6.1 文件上传配置添加依赖:

commons-fileupload

commons-fileupload

1.4

配置文件上传解析器:

<

!-- 最大上传大小:10MB -->

6.2 文件上传实现

@PostMapping("/upload")

public String upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {

if (!file.isEmpty()) {

// 获取上传目录

String uploadDir = request.getServletContext().getRealPath("/upload/");

File dir = new File(uploadDir);

if (!dir.exists()) {

dir.mkdirs(); // 创建目录

}

// 保存文件

String fileName = file.getOriginalFilename();

File destFile = new File(uploadDir + fileName);

file.transferTo(destFile);

}

return "redirect:/file/list";

}

6.3 文件下载实现

@GetMapping("/download")

public ResponseEntity download(String fileName, HttpServletRequest request) throws IOException {

// 获取文件路径

String filePath = request.getServletContext().getRealPath("/upload/") + fileName;

File file = new File(filePath);

// 设置响应头

HttpHeaders headers = new HttpHeaders();

String downloadFileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");

headers.setContentDispositionFormData("attachment", downloadFileName);

headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

// 读取文件并返回

return new ResponseEntity<>

(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);

}

七、拦截器(Interceptor)拦截器用于在请求处理前后执行自定义逻辑,如登录验证、日志记录、性能监控等。

7.1 自定义拦截器

public class LoginInterceptor implements HandlerInterceptor {

// 请求处理前执行(返回 true 则继续,false 则中断)

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

// 验证登录状态

HttpSession session = request.getSession();

if (session.getAttribute("user") == null) {

// 未登录,重定向到登录页

response.sendRedirect(request.getContextPath() + "/login");

return false;

}

return true;

}

// 请求处理后、视图渲染前执行

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

// 可修改模型数据

}

// 整个请求完成后执行(视图渲染后)

@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

// 可记录日志、释放资源

}

}

7.2 配置拦截器在 spring-mvc.xml 中配置:

<

!-- 拦截所有请求 -->

<

!-- 排除登录相关请求 -->

<

!-- 自定义拦截器 -->

八、异常处理SpringMVC 提供了全局异常处理机制,统一处理应用中的异常。

8.1 自定义异常类

public class BusinessException extends RuntimeException {

private String message;

public BusinessException(String message) {

this.message = message;

}

@Override

public String getMessage() {

return message;

}

}

8.2 全局异常处理器

@ControllerAdvice // 全局异常处理注解

public class GlobalExceptionHandler {

// 处理 BusinessException 异常

@ExceptionHandler(BusinessException.class)

public ModelAndView handleBusinessException(BusinessException e) {

ModelAndView mav = new ModelAndView();

mav.addObject("errorMsg", e.getMessage());

mav.setViewName("error"); // 跳转到错误页面

return mav;

}

// 处理所有未捕获的异常

@ExceptionHandler(Exception.class)

public ModelAndView handleException(Exception e) {

ModelAndView mav = new ModelAndView();

mav.addObject("errorMsg", "系统异常:" + e.getMessage());

mav.setViewName("error");

return mav;

}

}

九、RESTful 风格开发RESTful 是一种软件架构风格,通过 HTTP 方法(GET/POST/PUT/DELETE)表示对资源的操作,SpringMVC 对 RESTful 提供良好支持。

9.1 RESTful API 设计示例

9.2 实现 RESTful Controller

@RestController // 等同于 @Controller + @ResponseBody

@RequestMapping("/api/users")

public class UserRestController {

@Autowired

private UserService userService;

// 查询所有用户

@GetMapping

public List

findAll() {

return userService.findAll();

}

// 查询单个用户

@GetMapping("/{id}")

public User findById(@PathVariable Integer id) {

return userService.findById(id);

}

// 添加用户

@PostMapping

public ResponseEntity add(@RequestBody User user) { // @RequestBody 接收 JSON

userService.add(user);

return new ResponseEntity<>

(HttpStatus.CREATED); // 201 状态码

}

// 更新用户

@PutMapping("/{id}")

public ResponseEntity update(@PathVariable Integer id, @RequestBody User user) {

user.setId(id);

userService.update(user);

return new ResponseEntity<>

(HttpStatus.NO_CONTENT); // 204 状态码

}

// 删除用户

@DeleteMapping("/{id}")

public ResponseEntity delete(@PathVariable Integer id) {

userService.delete(id);

return new ResponseEntity<>

(HttpStatus.NO_CONTENT);

}

}

十、实战案例:用户管理系统10.1 功能设计实现用户的 CRUD 操作,包括:

用户列表展示(分页)添加用户修改用户删除用户查看用户详情10.2 代码实现(核心部分)10.2.1 Service 层

public interface UserService {

List findAll(int pageNum, int pageSize); // 分页查询

User findById(Integer id);

void add(User user);

void update(User user);

void delete(Integer id);

}

@Service

public class UserServiceImpl implements UserService {

@Autowired

private UserMapper userMapper;

@Override

public List findAll(int pageNum, int pageSize) {

PageHelper.startPage(pageNum, pageSize); // 分页插件

return userMapper.findAll();

}

// 其他方法实现...

}

10.2.2 Controller 层

@Controller

@RequestMapping("/user")

public class UserController {

@Autowired

private UserService userService;

// 分页查询用户列表

@GetMapping("/list")

public String list(

@RequestParam(defaultValue = "1") int pageNum,

@RequestParam(defaultValue = "5") int pageSize,

Model model) {

List

users = userService.findAll(pageNum, pageSize);

PageInfo pageInfo = new PageInfo<>

(users);

model.addAttribute("pageInfo", pageInfo);

return "user/list";

}

// 添加用户

@GetMapping("/toAdd")

public String toAdd() {

return "user/add";

}

@PostMapping("/add")

public String add(User user) {

userService.add(user);

return "redirect:/user/list";

}

// 其他方法...

}

10.2.3 视图页面(user/list.jsp)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

用户列表

ID 用户名 年龄 操作

${user.id}

${user.username}

${user.age}

修改

删除

<

!-- 分页控件 -->

首页

上一页

下一页

尾页

十一、学习资源与进阶方向11.1 官方资源Spring 官方文档 SpringMVC 官方示例

11.2 进阶学习方向SpringMVC 与 Spring Boot 整合:简化配置,提高开发效率前后端分离开发:结合 Vue/React 等前端框架,通过 JSON 交互安全框架整合:集成 Spring Security 或 Shiro 实现权限控制API 文档生成:使用 Swagger 自动生成 API 文档异步请求处理:学习 @Async、WebFlux 等异步处理技术

更多尼泊尔内容

2024年保护隐私,拒绝蹭网:推荐的十款防蹭网软件
bet28365365官网

2024年保护隐私,拒绝蹭网:推荐的十款防蹭网软件

🗓️ 07-04 👁️ 4986
手机欠费将影响征信?多地电信回应
office365邮箱手机版

手机欠费将影响征信?多地电信回应

🗓️ 02-10 👁️ 6588
期的五笔怎么打?期的五笔拆分图.
office365邮箱手机版

期的五笔怎么打?期的五笔拆分图.

🗓️ 08-31 👁️ 1977
TikTok精准引流群控攻略:如何批量引流高效获客?
office365邮箱手机版

TikTok精准引流群控攻略:如何批量引流高效获客?

🗓️ 08-15 👁️ 6671
《伤寒论》、《千金方药》中的药物计量与换算
office365邮箱手机版

《伤寒论》、《千金方药》中的药物计量与换算

🗓️ 09-06 👁️ 755
大连中兴陶瓷店面风采
office365邮箱手机版

大连中兴陶瓷店面风采

🗓️ 02-18 👁️ 2472
微信下载的文件存在手机什么位置?详细操作指南,看这篇就够了
四川绵阳电信宽带套餐价格表2024:最新资费一览
bet28365365官网

四川绵阳电信宽带套餐价格表2024:最新资费一览

🗓️ 08-24 👁️ 4707
地下城与勇士地轨中心深渊怎么开?(地轨中心深渊刷哪个图)
office365邮箱手机版

地下城与勇士地轨中心深渊怎么开?(地轨中心深渊刷哪个图)

🗓️ 07-30 👁️ 1140