SpringMVC 从入门到精通

前言

在 Java EE 开发中,Servlet 作为传统的控制层实现方式存在诸多缺陷,而 SpringMVC 作为 Spring 框架的核心模块之一,是基于 MVC 设计模式的轻量级 Web 开发框架,现已成为企业级项目表述层开发的首选方案。本文将从 SpringMVC 概述、环境搭建、核心注解、参数处理、数据传递到 JSON 交互,全方位讲解 SpringMVC 入门核心知识点。

一、SpringMVC 概述

1.1 为什么选择 SpringMVC?

先看传统 Servlet 的实现案例:

java 复制代码
@WebServlet("/addUser") 
public class AddUserServlet extends HttpServlet {
    private UserService userService = new UserServiceImpl();
    @Override
    protected void doPost(HttpServletRequest req, 
                     HttpServletResponse resp) throws ServletException, IOException {
        // 手动接收所有参数,繁琐且易出错
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String sex = req.getParameter("sex");
        Integer age = Integer.parseInt(req.getParameter("age"));
        String address = req.getParameter("address");

        userService.addUser(username, password, sex, age, address);
        resp.sendRedirect("selectUser");
    }
}

Servlet 的核心缺陷

  • 一个 Servlet 实例只能处理一个请求,导致类爆炸
  • 参数接收需手动解析,类型转换繁琐(如 String 转 Integer)
  • 代码耦合度高,不利于维护和扩展

1.2 MVC 设计模式

MVC 将软件分为三层,各司其职:

层级 说明 具体实现
Model(模型层) 处理数据 数据承载 Bean(User/Student)、业务处理 Bean(Service/Dao)
View(视图层) 交互展示 HTML/JSP 页面
Controller(控制层) 接收请求 / 响应浏览器 Servlet/SpringMVC 的 Controller

MVC 工作流程:用户通过视图层发送请求 → 控制器接收请求 → 调用模型层处理数据 → 模型层返回结果给控制器 → 控制器渲染视图 → 响应给浏览器

1.3 SpringMVC 核心定位

  • SpringMVC 本质上等价于 Servlet,是 Spring 为控制层提供的完整解决方案
  • 对比 Struts2 等框架,SpringMVC 具有轻量、高效、易整合 Spring 生态的优势
  • 是当前 Java EE 项目表述层开发的首选框架

二、SpringMVC 入门环境搭建

2.1 工程创建(IDEA)

  1. 创建 Maven 工程,选择maven-archetype-webapp(或普通 Maven 工程后添加 Web 支持)
  2. 右键项目 → Add Framework Support → 勾选Web Application
  3. 将生成的web目录拖拽到main下,并重命名为webapp(关键!)

2.2 核心依赖(pom.xml)

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hg</groupId>
    <artifactId>SpringMVC_day01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <!-- Spring核心依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>
        <!-- SpringMVC核心依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>
        <!-- Servlet依赖(仅编译时有效) -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <!-- Tomcat插件配置 -->
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>8080</port>
                    <path>/</path>
                    <!-- 解决GET请求中文乱码 -->
                    <uriEncoding>UTF-8</uriEncoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.3 入门案例核心代码

(1)前端页面(index.jsp)
XML 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>SpringMVC入门</title>
  </head>
  <body>
    <a href="/hello">Hello SpringMVC</a>
  </body>
</html>
(2)控制器(HelloController.java)
java 复制代码
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

// 交给Spring容器管理
@Controller
public class HelloController {
    // 建立请求URL与方法的映射关系
    @RequestMapping("/hello")
    public ModelAndView hello() {
        // 封装模型数据和视图信息
        ModelAndView mv = new ModelAndView();
        // 等价于request.setAttribute("hello", "欢迎你 springmvc!!")
        mv.addObject("hello", "欢迎你 springmvc!!");
        // 设置逻辑视图名(由视图解析器拼接物理路径)
        mv.setViewName("success");
        return mv;
    }
}
(3)SpringMVC 配置文件(springmvc.xml)
XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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) -->
    <context:component-scan base-package="com.hg"></context:component-scan>

    <!-- 配置视图解析器(拼接逻辑视图名) -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀:视图文件所在目录 -->
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <!-- 后缀:视图文件扩展名 -->
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!-- 开启SpringMVC注解支持(自动配置HandlerMapping/HandlerAdapter) -->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>
(4)视图页面(success.jsp)
XML 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>成功页</title>
</head>
<body>
    <h2>${hello}</h2>
</body>
</html>
(5)Web 配置文件(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_4_0.xsd"
         version="4.0">
    <!-- 配置SpringMVC前端控制器 -->
    <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.xml</param-value>
        </init-param>
        <!-- 容器启动时立即加载Servlet(优先级1) -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- 映射所有请求(/ 不包含.jsp,/* 包含所有) -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 解决POST请求中文乱码过滤器 -->
    <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>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

2.4 测试访问

启动 Tomcat,访问http://localhost:8080/hello,页面显示欢迎你 springmvc!!即为成功。

三、SpringMVC 核心组件与执行流程

3.1 核心组件

组件 核心作用
DispatcherServlet(前端控制器) 流程控制中心,协调所有组件
HandlerMapping(处理器映射器) 根据请求 URL 查找对应的 Handler
HandlerAdapter(处理器适配器) 适配并执行 Handler(适配器模式)
ViewResolver(视图解析器) 将逻辑视图名解析为物理视图地址
View(视图) 渲染模型数据,响应浏览器

3.2 完整执行流程

  1. 用户发起请求到 DispatcherServlet
  2. DispatcherServlet 请求 HandlerMapping 查找 Handler
  3. HandlerMapping 返回 HandlerExecutionChain(包含 Handler + 拦截器)
  4. DispatcherServlet 通过 HandlerAdapter 执行 Handler
  5. Handler 执行完成返回 ModelAndView
  6. DispatcherServlet 请求 ViewResolver 解析视图
  7. ViewResolver 返回 View 对象
  8. DispatcherServlet 渲染 View(将 Model 数据放入 request)
  9. DispatcherServlet 响应结果给用户

四、RequestMapping 注解详解

4.1 核心作用

建立请求 URL 与控制器方法的映射关系,可作用于方法

4.2 窄化路径(类级别)

java 复制代码
@Controller
@RequestMapping("/account") // 第一级路径
public class AccountController {
    @RequestMapping("/findAccount") // 第二级路径
    public ModelAndView findAccount() {
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg", "窄化路径测试");
        mv.setViewName("success");
        return mv;
    }
}

访问路径:http://localhost:8080/account/findAccount

4.3 指定请求方式(method 属性)

java 复制代码
@RequestMapping(value = "/findAccount1", method = RequestMethod.POST)
public ModelAndView findAccount1() {
    ModelAndView mv = new ModelAndView();
    mv.addObject("msg", "POST请求测试");
    mv.setViewName("success");
    return mv;
}
  • 仅允许 POST 请求访问,GET 请求会返回 405 错误
  • 可同时指定多个请求方式:method = {RequestMethod.GET, RequestMethod.POST}

五、Controller 方法返回值类型

5.1 返回 ModelAndView

最基础方式,封装模型数据和视图名(如入门案例)。

5.2 返回字符串

(1)逻辑视图名
java 复制代码
@RequestMapping("/findAccount2")
public String findAccount2(Model model) {
    model.addAttribute("msg", "返回字符串视图名");
    return "success"; // 逻辑视图名,由视图解析器拼接路径
}
(2)重定向(Redirect)
java 复制代码
@RequestMapping("/findAccount3")
public String findAccount3() {
    // 重定向到另一个方法(浏览器地址栏变化,新请求)
    return "redirect:/account/findAccount4";
}

@RequestMapping("/findAccount4")
public String findAccount4(Model model) {
    model.addAttribute("msg", "重定向测试");
    return "success";
}
(3)转发(Forward)
java 复制代码
@RequestMapping("/findAccount3")
public String findAccount3() {
    // 转发到另一个方法(地址栏不变,共用request)
    return "forward:/account/findAccount4";
}

六、参数接收全攻略

6.1 基本数据类型

java 复制代码
@RequestMapping("/findAccount5")
public String findAccount5(String username, Integer age, Model model) {
    model.addAttribute("msg", "用户名:" + username + ",年龄:" + age);
    return "success";
}

访问路径:http://localhost:8080/account/findAccount5?username=eric&age=22

6.2 POJO 类型参数绑定

(1)定义 POJO
java 复制代码
public class Account implements Serializable {
    private Integer id;
    private String name;
    private Float money;
    private String pwd;
    private String address;
    // getter/setter/toString
}
(2)接收参数
java 复制代码
@RequestMapping("/saveAccount")
public String saveAccount(Account account, Model model) {
    model.addAttribute("msg", account.toString());
    return "success";
}
(3)前端表单
html 复制代码
<form action="account/saveAccount" method="post">
    账户名称:<input type="text" name="name"><br/>
    账户金额:<input type="text" name="money"><br/>
    账户密码:<input type="text" name="pwd"><br/>
    账户地址:<input type="text" name="address"><br/>
    <input type="submit" value="保存">
</form>

6.3 RESTful 风格传参(@PathVariable)

(1)RESTful 核心思想

URL 定位资源,HTTP 动词(GET/POST/PUT/DELETE)描述操作:

传统 URL RESTful URL 请求方式 操作
/user/query?id=1 /user/1 GET 查询
/user/save /user POST 新增
/user/update /user PUT 修改
/user/delete?id=1 /user/1 DELETE 删除
(2)代码实现
java 复制代码
@RequestMapping("/findAccount7/{id}")
public String findAccount7(@PathVariable Integer id, Model model) {
    model.addAttribute("msg", "RESTful传参:" + id);
    return "success";
}

访问路径:http://localhost:8080/account/findAccount7/123

相关推荐
Francek Chen7 小时前
【大数据存储与管理】分布式数据库HBase:05 HBase运行机制
大数据·数据库·hadoop·分布式·hdfs·hbase
zzzzzwbetter7 小时前
Hadoop完全分布式部署-Master的NameNode以及Slaver2的DataNode未启动
大数据·hadoop·分布式
weixin_449310849 小时前
ETL转换和数据写入小满OKKICRM的技术细节
数据仓库·php·etl
IvanCodes10 小时前
Hive IDE连接及UDF实战
ide·hive·hadoop
yumgpkpm11 小时前
华为昇腾910B 开源软件GPUStack的介绍(Cloudera CDH、CDP)
人工智能·hadoop·elasticsearch·flink·kafka·企业微信·big data
lifewange1 天前
Hive数据库
数据库·hive·hadoop
五月天的尾巴2 天前
hive数据库模糊查询表名
hive·查询表名
蓝魔Y2 天前
hive—1.1、执行优化
hive
快乐非自愿2 天前
OpenClaw 生态适配:Hadoop/Hive 技能现状与企业级集成方案
大数据·hive·hadoop·分布式·openclaw