欢迎光临
我们一直在努力

Spring MVC :从入门到精通(上)

一、Spring MVC概述

1.1为什么使用Spring MVC?

servlet案例:

@WebServlet("/addUser") //1、该Servlet的URL映射为“/addUser”
public class AddUserServlet extends HttpServlet {

private UserService userService = new UserServiceImpl();

@Override
protected void doPost(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
//2、接收前台传递的参数
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缺陷:

        1.一个servlet实例只能处理一个请求

        2.参数接收太麻烦

1.2 MVC 设计模式

MVC 是一种软件分层设计模式,将应用分为三层:

  • Model(模型层):JavaBean,分为两类
    • 数据承载 Bean:如 pojo/User、Student(存储业务数据)
    • 业务处理 Bean:如 Service、Dao(处理业务逻辑 / 数据访问)
  • View(视图层):HTML/JSP 页面,负责交互和数据展示
  • Controller(控制层):Servlet,接收请求、响应浏览器

MVC 工作流程:

        View—–>Controller—–>Model

        用户通过视图层发起请求 → 控制器接收请求 → 调用模型层处理数据 → 模型层返回结果给控制器 → 控制器选择视图渲染数据 → 响应给浏览器

MVC 和三层架构的关系:

对比维度三层架构MVC
分层关系 典型上下依赖关系,上层依赖下层 相互协作关系,不存在上下层
划分依据 基于业务逻辑划分 基于页面 划分

1.3 SpringMVC 介绍

  • SpringMVC 是 Spring 框架的核心模块,基于 MVC 设计模式的轻量级 Web 框架(本质等价于 Servlet)
  • 是 Java EE 项目表述层开发的首选方案,提供了完备的控制层解决方案

二、SpringMVC 入门案例

2.1 环境搭建

2.1.1 创建工程并添加 Web 支持
  • 新建 Maven 工程,右键选择Add framework support…
  • 勾选 Web Application,添加 Web 支持
  • 将 web 目录拖拽到 main 目录下,重命名为 webapp(注意:先加框架支持,再设置打包方式)
  • 注意:

  • 先添加框架支持,再设置打包方式

  • 将web目录要拖拽到main目录下,并改名为webapp

  • 2.1.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>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.8.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.8.RELEASE</version>
    </dependency>

    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
    </dependency>
    </dependencies>
    <build>
    <plugins>
    <!– 配置Tomcat插件 –>
    <plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
    <configuration>
    <!–端口号–>
    <port>8080</port>
    <!–项目名–>
    <path>/</path>
    </configuration>
    </plugin>
    </plugins>
    </build>
    </project>

    2.2 编写核心代码

    2.2.1 前端页面(index.jsp)

    jsp

    <%@ 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.2.2 控制器(HelloController)

    java

    @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;
    }
    }

    2.2.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">

    <!– 扫描注解所在的包 –>
    <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>

    2.2.4 视图页面(success.jsp)

    jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>成功页</title>
    </head>
    <body>
    <h2>${hello}</h2>
    </body>
    </html>

    2.2.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">
    <!– 配置前端控制器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.xml</param-value>
    </init-param>
    <!– 容器启动时加载Servlet –>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!– /:处理所有请求(排除JSP);/*:处理所有请求(包含JSP) –>
    <url-pattern>/</url-pattern>
    </servlet-mapping>
    </web-app>

    2.3 测试

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

    2.4 SpringMVC 核心组件

  • DispatcherServlet(前端控制器):流程控制中心,调用其他组件处理请求,降低耦合
  • HandlerMapping(处理器映射器):根据请求 URL 查找对应的 Handler(处理器)
  • Handler(处理器):自定义的 Controller,处理具体业务逻辑
  • HandlerAdapter(处理器适配器):适配并执行 Handler(适配器模式)
  • ViewResolver(视图解析器):将逻辑视图名解析为物理视图地址
  • View(视图):渲染模型数据,将结果响应给浏览器
  • 2.5 SpringMVC 执行流程

        DispatcherServlet(前端控制器):接受请求,加载springmvc.xml
        HandlerMapping(处理器映射器):查找handler
        HandlerAdapter(处理器适配器):调用handler
        ViewResolver(视图解析器):拼接jsp的路径
        View(视图渲染器):把数据填充到request,跳转页面

    • 用户发起请求到 DispatcherServlet
    • DispatcherServlet 请求 HandlerMapping 查找 Handler
    • HandlerMapping 返回 HandlerExecutionChain(包含 Handler + 拦截器)
    • DispatcherServlet 调用 HandlerAdapter 执行 Handler
    • HandlerAdapter 执行 Handler,返回 ModelAndView
    • DispatcherServlet 请求 ViewResolver 解析视图
    • ViewResolver 返回 View 对象
    • DispatcherServlet 渲染视图(将 Model 数据填充到 View)
    • DispatcherServlet 响应结果给用户

    三、RequestMapping 注解

    3.1 核心作用

    建立请求 URL 和处理方法的映射关系(Map<url,方法>),可标注在类 / 方法上:

    • 类上:定义请求 URL 的第一级目录(窄化路径)
    • 方法上:建立url 和 方法 的映射关系

    3.2 核心属性

    • value/path:指定请求 URL
    • method:指定请求方式(RequestMethod.GET/POST 等)

    3.3 实战示例

    3.3.1 窄化路径

    java

    @Controller
    @RequestMapping("/account") // 第一级目录
    public class AccountController {
    @RequestMapping("/findAccount") // 第二级目录
    public ModelAndView findAccount() {
    ModelAndView mv = new ModelAndView();
    mv.addObject("msg", "欢迎你 springmvc");
    mv.setViewName("success");
    return mv;
    }
    }

    index.jsp

    <a href="/account/findAccount">窄化路径</a>

    3.3.2 method属性指定请求方式

    java

    @Controller
    @RequestMapping("/account")
    public class AccountController {
    // 仅允许POST请求
    @RequestMapping(value = "/findAccount1", method = RequestMethod.POST)
    public ModelAndView findAccount1() {
    ModelAndView mv = new ModelAndView();
    mv.addObject("msg", "欢迎你 springmvc");
    mv.setViewName("success");
    return mv;
    }
    }

    POST 请求测试:

    <form action="account/findAccount1" method="post">
    <input type="submit" value="POST请求测试">
    </form>

    四、Controller 方法返回值

    4.1 返回 ModelAndView

    封装模型数据 + 视图名称,示例见 2.2.2。

    4.2 返回字符串

    4.2.1 逻辑视图名

    java

    @RequestMapping("/findAccount2")
    public String findAccount2(Model model) {
    model.addAttribute("msg", "返回字符串视图名");
    return "success"; // 逻辑视图名,由视图解析器拼接路径
    }

    4.2.2 Redirect 重定向

    java

    @RequestMapping("/findAccount3")
    public String findAccount3() {
    // 重定向到另一个方法,浏览器地址栏变化,新请求
    return "redirect:/account/findAccount4";
    }

    @RequestMapping("/findAccount4")
    public String findAccount4(Model model) {
    model.addAttribute("msg", "SpringMVC重定向");
    return "success";
    }

    4.2.3 Forward 转发

    java

    @RequestMapping("/findAccount3")
    public String findAccount3() {
    // 转发到另一个方法,地址栏不变,共用请求
    return "forward:/account/findAccount4";
    }

    五、请求参数接收

    jsp—>参数—>controller

    SpringMVC 通过方法形参接收参数,自动完成类型转换(特殊场景需自定义转换器)。

    5.1 基本数据类型

    java

    @RequestMapping("/findAccount5")
    public String findAccount5(String username, Integer age, Model model){
    model.addAttribute("msg", username + " " + age);
    return "success";
    }

    index.jsp

    <a href="/account/findAccount5?username=eric&age=22">基本类型传参</a>

    5.2 POJO 类型

    5.2.1 定义 POJO

    java

    public class Account implements Serializable {
    private Integer id;
    private String name;
    private Float money;
    private Address address; // 嵌套POJO
    // getter/setter/toString
    }

    public class Address implements Serializable {
    private String provinceName;
    private String cityName;
    // getter/setter/toString
    }

    5.2.2 接收 POJO 参数

    java

    @RequestMapping("/saveAccount")
    public String saveAccount(Account account, Model model){
    model.addAttribute("msg", account);
    return "success";
    }

    index.jsp

    <form action="account/saveAccount" method="post">
    账户名称:<input type="text" name="name"><br/>
    账户金额:<input type="text" name="money"><br/>
    省份:<input type="text" name="address.provinceName"><br/>
    城市:<input type="text" name="address.cityName"><br/>
    <input type="submit" value="保存">
    </form>

    5.3 RESTful 风格

    5.3.1 核心思想

    URL 定位资源,HTTP 动词描述操作:

    • GET:查询(/user/1)
    • POST:新增(/user)
    • PUT:修改(/user)
    • DELETE:删除(/user/1)
    5.3.2 @PathVariable 注解

    绑定 URL 占位符到方法形参:

    java

    @RequestMapping("/findAccount7/{id}")
    public String findAccount7(@PathVariable Integer id, Model model){
    model.addAttribute("msg", "RESTful传参:" + id);
    return "success";
    }

    index.jsp

    <a href="/account/findAccount7/123">RESTful传参</a>

    5.4 解决参数乱码

    5.4.1 POST 请求(编码过滤器)

    在 web.xml 添加:

    xml

    <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>

    5.4.2 GET 请求(Tomcat 编码)

    修改 pom.xml 的 Tomcat 插件:

    xml

    <plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
    <configuration>
    <port>8080</port>
    <path>/</path>
    <uriEncoding>UTF-8</uriEncoding> <!– GET请求编码 –>
    </configuration>
    </plugin>

    5.5 自定义类型转换器

    5.5.1 场景:日期类型转换

    前端传递字符串日期(如 2024-01-01),后台用 Date 接收,需自定义转换器:

    5.5.2 实现步骤
  • 定义转换器类:
  • java

    运行

    public class DateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
    try {
    DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    return format.parse(source);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return null;
    }
    }

  • 配置转换器(springmvc.xml):
  • xml

    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

    <!– 配置类型转换器工厂 –>
    <bean id="conversionService"
    class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
    <set>
    <bean class="com.hg.converter.DateConverter"></bean>
    </set>
    </property>
    </bean>

    5.6 ServletAPI 接收参数

    直接将 HttpServletRequest/HttpServletResponse 作为方法形参:

    java

    运行

    @RequestMapping("/findAccount8")
    public String findAccount8(HttpServletRequest request, HttpServletResponse response){
    String username = request.getParameter("username");
    String age = request.getParameter("age");
    request.setAttribute("msg", username + " " + age);
    return "success";
    }

    六、数据传递

    6.1 ModelAndView 传递

    java

    运行

    @RequestMapping("/findAccount9")
    public ModelAndView findAccount9(ModelAndView mv) {
    mv.addObject("msg", "ModelAndView传递数据");
    mv.setViewName("success");
    return mv;
    }

    6.2 Model 传递

    java

    运行

    @RequestMapping("/findAccount10")
    public String findAccount10(Model model) {
    model.addAttribute("msg", "Model传递数据");
    return "success";
    }

    6.3 ServletAPI 传递

    java

    运行

    @RequestMapping("/findAccount11")
    public String findAccount11(HttpServletRequest request){
    request.setAttribute("msg", "ServletAPI传递数据");
    return "success";
    }

    七、JSON 数据处理

    7.1 添加依赖

    SpringMVC 默认使用 Jackson 处理 JSON:

    xml

    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
    </dependency>

    7.2 核心注解

    • @RequestBody:接收前端 JSON 字符串,转为 Java 对象
    • @ResponseBody:将 Java 对象转为 JSON 字符串,响应给前端

    7.3 实战案例

    7.3.1 后端 Controller

    java

    运行

    @RequestMapping("/saveAccount2")
    @ResponseBody // 响应JSON
    public Map<String, Object> saveAccount2(@RequestBody Account account){
    Map<String, Object> map = new HashMap<>();
    map.put("status", 200);
    map.put("msg", account);
    return map;
    }

    7.3.2 前端 AJAX

    html

    预览

    <input type="button" value="测试JSON交互" onClick="testJson()"/>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script type="text/javascript">
    function testJson(){
    axios.post('/account/saveAccount2',{"id":1,"name":"张二狗","money":999.0})
    .then(response => {
    if(response.data.status === 200){
    alert(response.data.msg.name);
    }
    })
    .catch(error => console.error('请求失败:', error));
    }
    </script>

    总结

    本文从 SpringMVC 的核心概念出发,逐步讲解了环境搭建、入门案例、核心注解、参数接收、数据传递、JSON 交互等核心知识点。SpringMVC 作为轻量级 Web 框架,通过分层设计和注解化开发,大幅简化了控制层开发流程,是 Java Web 开发的必备技能。后续将继续讲解拦截器、文件上传、异常处理等高级特性,敬请关注!

    赞(0)
    未经允许不得转载:171主机测评 » Spring MVC :从入门到精通(上)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址