1.概述

  • Spring 为展现层提供的基于 MVC 设计理念的优秀的 Web 框架,是目前最主流的 MVC 框架之一
  • Spring3.0 后全面超越 Struts2,成为最优秀的 MVC 框架。
  • SpringMVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口。
  • 支持 REST 风格的 URL 请求。
  • 采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性。
  • 基于Servlet实现,方便运行于常用Java EE容器。

1.1 MVC模式

MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式:

  • Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。
  • View(视图)是应用程序中处理数据显示的部分。
  • Controller(控制器)是应用程序中处理用户交互的部分。

    优点:耦合性低、重用性高、可维护性高。

1.2 Spring MVC 模式

前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生成相应的响应发送到客户端。

Spring MVC使用Servlet来实现(DispatcherServlet)。DispatcherServlet 作为前置控制器是web服务器的入口,是spring mvc最重要的一个类。

1.3 SpringMVC 是什么

1)一种轻量级的、基于 MVC 的 Web 层应用框架。偏前端而不是基于业务逻辑层。Spring框架的一个后续产品。

2)Spring 框架结构图(新版本):

1.4SpringMVC 能干什么

  1. 天生与 Spring 框架集成,如:(IOC,AOP)
  2. 支持 Restful 风格
  3. 进行更简洁的 Web 层开发
  4. 支持灵活的 URL 到页面控制器的映射
  5. 非常容易与其他视图技术集成,如:Velocity、FreeMarker 等等
  6. 因为模型数据不存放在特定的 API 里,而是放在一个 Model 里(Map 数据结构实现, 因此很容易被其他框架使用)
  7. 非常灵活的数据验证、格式化和数据绑定机制、能使用任何对象进行数据绑定, 不必实现特定框架的 API
  8. 更加简单、强大的异常处理
  9. 对静态资源的支持
  10. 支持灵活的本地化、主题等解析

1.5 SpringMVC 常用组件

  • DispatcherServlet:前端控制器
  • Controller:处理器/页面控制器,做的是 MVC 中的 C 的事情,但控制逻辑转移到前端控制器了,用于对请求进行处理
  • HandlerMapping :请求映射到处理器,找谁来处理,如果映射成功返回一个 HandlerExecutionChain 对象(包含一个 Handler 处理器(页面控制器)对象、多 个 HandlerInterceptor 拦截器对象)
  • ViewResolver: 视图解析器,找谁来处理返回的页面。把逻辑视图解析为具体 的 View,进行这种策略模式,很容易更换其他视图技术; 如 InternalResourceViewResolver 将逻辑视图名映射为 JSP 视图
  • LocalResolver:本地化、国际化
  • MultipartResolver:文件上传解析器
  • HandlerExceptionResolver:异常处理器

1.6 SpringMVC常用注解

@Controller

  负责注册一个bean 到spring 上下文中
@RequestMapping

  注解为控制器指定可以处理哪些 URL 请求
@RequestBody

  该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上 ,再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上
浏览器发ajax请求,设置成contentType:”application/json”,以json字符串的方式发送对象,服务器端通过@RequestBody把接受道德字符串转成java对象

@ResponseBody

   该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区

@RestController

@ModelAttribute    

  在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法

  在方法的入参前使用 @ModelAttribute 注解:可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数 –绑定到对象中,再传入入参将方法入参对象添加到模型中

@RequestParam 

  在处理方法入参处使用 @RequestParam 可以把请求参 数传递给请求方法

@PathVariable

  绑定 URL 占位符到入参
@ExceptionHandler

  注解到方法上,出现异常时会执行该方法
@ControllerAdvice

  使一个Contoller成为全局的异常处理类,类中用@ExceptionHandler方法注解的方法可以处理所有Controller发生的异常

2 SpringMVC-HelloWorld

2.1.新建 maven工程,添加web支持,引入各种 jar 包依赖




2.2 引入jar包依赖

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.0.RELEASE</version>
</dependency>

2.3. 在 web.xml 中配置 DispatcherServlet

<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">
<!-- 配置 SpringMVC 核心控制器: -->
<servlet>
    <servlet-name>springDispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 配置 DispatcherServlet 的初始化參數:设置文件的路径和文件名称 -->
    <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>springDispatcherServlet</servlet-name>
    <!--拦截所有请求-->
    <url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

*拦截所有请求应该将url-pattern的/换成/,这样可以拦截一切请求

新建对应的目录并且将其标记:

2.4 加入 SpringMVC 的配置文件:springmvc.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"
       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">
    <!-- 设置扫描组件的包: -->
    <context:component-scan base-package="net.suncaper"/>
</beans>

2.5 需要创建一个入口页面,index.jsp

<a href="${pageContext.request.contextPath}/helloworld">HelloWorld</a>

2.6 编写处理请求的处理器,并标识为处理器

package net.suncaper.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
/**
 * @author nedli
 */
//1. 用@Controller告诉Spring MVC这是一个处理器,可以处理页面请求
@Controller
public class HelloController {
    //2. 标志此方法处理 /hello 请求
    @RequestMapping("/hello")
    public String hello() {
        //3. 返回.jsp页面的路径,很麻烦
        return "/WEB-INF/views/hello.jsp";
    }
}

2.7. 配置视图解析器(简化路径配置)

<!-- 配置视图解析器:如何将控制器返回的结果字符串,转换为一个物理的视图文件(拼接页面地址)-->
    <bean id="internalResourceViewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

这个时候Controller改为

package net.suncaper.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
/**
 * @author nedli
 */
//1. 用@Controller告诉Spring MVC这是一个处理器,可以处理页面请求
@Controller
public class HelloController {
    //2. 标志此方法处理 /hello 请求,使用hello也是一样的效果哦
    @RequestMapping("/hello")
    public String hello() {
        //3. 返回.jsp页面的路径
        return "hello";
    }
}

2.8.部署测试

http://localhost:8080/SpringMVC_01_HelloWorld/index.jsp

3. HelloWorld 深度解析

3.1 HelloWorld 请求流程图解:


一般请求的映射路径名称和处理请求的方法名称最好一致(实质上方法名称任意);

经常有同学会出现配置上错误,把“/WEB-INF/views/”配置成了 “/WEB-INF/views”;

3.2 流程分析

基本步骤:

  • 客户端请求提交到 DispatcherServlet
  • 由 DispatcherServlet 控制器查询一个或多个 HandlerMapping,找到处理请求的 Controller
  • DispatcherServlet 将请求提交到 Controller(也称为 Handler)
  • Controller 调用业务逻辑处理后,返回 ModelAndView
  • DispatcherServlet 查询一个或多个 ViewResoler 视图解析器,找到 ModelAndView 指定的视图
  • 视图负责将结果显示到客户端.