Spring MVC 入门案例:从代码到原理的深度剖析

一、引言

Spring MVC 是一种基于 Java 的实现了 MVC 设计模式的请求驱动类型的轻量级 Web 框架,它为开发 Web 应用提供了强大而灵活的解决方案。本文将通过一个简单的 Spring MVC 入门案例,详细介绍其工作流程,帮助读者深入理解 Spring MVC 的运行机制。

二、环境准备

在开始编写代码之前,我们需要准备好开发环境。本案例使用 Maven 进行项目管理,因此需要在 pom.xml 中添加必要的依赖。以下是 pom.xml 的代码:

XML 复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.qcby</groupId>
  <artifactId>01</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>01 Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <!-- 版本锁定 -->
  <properties>
    <spring.version>5.3.23</spring.version>
    <servlet.api.version>4.0.1</servlet.api.version>
    <jsp.api.version>2.3.3</jsp.api.version>
    <junit.version>4.13.2</junit.version>
  </properties>

  <dependencies>
    <!-- Spring 相关依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- Servlet API -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>${servlet.api.version}</version>
      <scope>provided</scope>
    </dependency>

    <!-- JSP API -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>${jsp.api.version}</version>
      <scope>provided</scope>
    </dependency>

    <!-- 测试依赖 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <finalName>01</finalName>
  </build>
</project>

这些依赖包含了 Spring 框架、Servlet API、JSP API 以及测试所需的 JUnit 库。

三、配置文件编写

3.1 web.xml 配置

web.xml 是 Web 应用的核心配置文件,主要用于配置 Servlet、过滤器等。以下是 web.xml 的代码:

XML 复制代码
<?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_3_1.xsd"
         version="3.1">

  <display-name>Spring MVC Application</display-name>

  <!-- 添加字符编码过滤器 -->
  <filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>
  • 字符编码过滤器:用于设置请求和响应的字符编码为 UTF-8,避免中文乱码问题。
  • DispatcherServlet :Spring MVC 的核心 Servlet,负责接收所有的请求并进行分发处理。通过 contextConfigLocation 指定其配置文件为 springmvc.xml
  • Servlet 映射 :将所有以 .do 结尾的请求映射到 DispatcherServlet

3.2 springmvc.xml 配置

springmvc.xml 是 Spring MVC 的配置文件,主要用于启用注解驱动、配置组件扫描和视图解析器。以下是 springmvc.xml 的代码:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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/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">

    <!-- 启用注解驱动 -->
    <mvc:annotation-driven/>

    <!-- 配置组件扫描 -->
    <context:component-scan base-package="cn.tx.demo1"/>

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
  • 注解驱动 :启用 Spring MVC 的注解功能,如 @Controller@RequestMapping 等。
  • 组件扫描 :指定 Spring 容器扫描的包路径,自动发现并注册带有 @Controller 等注解的组件。
  • 视图解析器:用于将控制器返回的逻辑视图名解析为实际的 JSP 页面路径。

四、控制器编写

控制器是 Spring MVC 中处理请求的核心组件,负责接收请求、处理业务逻辑并返回视图。以下是 HelloController.java 的代码:

java 复制代码
package cn.tx.demo1;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;

@Controller
@RequestMapping("say")
public class HelloController {
    @RequestMapping(path = "hello.do", method = RequestMethod.GET, params = "username")
    public String sayHello(String username) {
        try {
            PrintStream out = new PrintStream(System.out, true, "UTF-8");
            out.println("入门方法执行了2...");
            out.println(username);
        } catch (UnsupportedEncodingException e) {
            System.out.println("入门方法执行了2...");
        }
        return "suc";
    }
}
  • @Controller 注解:将该类标记为控制器,Spring 容器会自动扫描并注册该类。
  • @RequestMapping 注解:用于映射请求路径和请求方法。这里将 /say/hello.do 的 GET 请求映射到 sayHello 方法,并且要求请求参数中包含 username
  • sayHello 方法:接收 username 参数,打印相关信息,并返回逻辑视图名 suc

五、视图页面编写

5.1 首页 index.jsp

java 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>入门程序</title>
</head>
<body>
<%--超链接--%>
<h3>入门</h3>
<form action="/say/hello.do" method="post">
    用户名:<input type="text" name="username"/>
    <button type="submit">提交</button>
</form>
<a href="/say/hello.do?username=张三" >入门程序</a>
</body>
</html>

该页面提供了一个表单和一个超链接,用于向 HelloController 发送请求。

5.2 成功页面 suc.jsp

java 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>成功</title>
</head>
<body>
<h3>入门成功了2...</h3>
</body>
</html>

当请求处理成功后,会跳转到该页面。

如下:

六、工作流程分析

6.1 请求发送

用户在浏览器中访问 index.jsp 页面,通过表单或超链接发送请求到 /say/hello.do

6.2 请求接收

请求到达 DispatcherServletDispatcherServlet 根据 web.xml 中的配置,将请求转发给 Spring MVC 框架处理

6.3 处理器映射

DispatcherServlet 根据 @RequestMapping 注解的配置,找到对应的控制器方法 HelloController.sayHello

6.4 处理器执行

调用 sayHello 方法,处理业务逻辑,接收并打印 username 参数。

6.5 视图解析

sayHello 方法返回逻辑视图名 sucDispatcherServlet 根据 springmvc.xml 中配置的视图解析器,将逻辑视图名解析为实际的 JSP 页面路径 /WEB-INF/pages/suc.jsp

6.6 视图渲染

DispatcherServlet 将请求转发到 suc.jsp 页面,渲染并返回给用户。

相关推荐
李慕婉学姐3 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆4 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin5 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20055 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉5 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国5 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882485 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈6 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_996 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
沛沛老爹6 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理