SpringMVC1️⃣MVC、入门、原理

1、MVC

1.1、说明

MVC 设计模式,用于应用程序的分层开发

  • Model(模型):提供数据(DAO、VO)和业务逻辑(Service)
  • View(视图):负责数据的可视化,即模型的展示。
  • Controller(控制器)
    • 接收视图层的用户请求,调度(Dispatcher)给模型进行处理。
    • 将处理返回的数据渲染视图。

1.2、发展

Model 1

早期 Web 开发,

分为视图层和模型层。

  • 优点:架构简单。

  • 缺点:模型层职责不单一(展示数据 + 接收处理请求)

    image-20210809152236100

Model 2

将项目分为 M-V-C 三层,即目前的 MVC 模式。

职责分明,利于维护

  • Controller:接收请求、调用业务逻辑、响应页面(跳转)

  • Model:处理业务逻辑(Service)、保存数据状态(DAO)

  • View:显示页面

    image-20210809152137166

2、Spring MVC

全称 Spring Web MVC(👉 官方文档

基于 Java Servlet API,实现 MVC 设计模式的轻量级 Web 框架。

  1. 核心:围绕 DispatcherServlet 设计,将请求分发到不同的处理器。
  2. 特点:
    1. 轻量级,简洁灵活,简单易学。
    2. 高效,基于请求响应的 MVC 框架。
    3. 与 Spiring 兼容性好,无缝结合。
    4. 约定大于配置。
    5. 功能强大:RESTful、数据验证、格式化、本地化、主题等。

2.1、对比

传统 web 开发中,通常每个业务对应一个 Servlet,项目臃肿。

Spring MVC:将 Servlet 的共性行为和特有行为分离

  • DispatcherServlet:抽取并封装共性行为,将请求分发到不同的处理器(也称前端控制器)

  • 处理器(handler):负责处理业务,通常是编写 Controller 作为处理器(也称后端控制器)

    image.png

2.2、开发步骤(❗)

2.2.1、环境搭建

  1. 添加 web 框架支持、集成 Tomcat

  2. 导入依赖:直接导入 webmvc 依赖,会自动导入相关的 spring 依赖

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

    image-20220326151358567

2.2.2、配置(❗)

SpringMVC 核心配置文件

  • SpringMVC 的配置与 Spring 分开编写,且通常命名 spring-mvc.xml

  • 开启注解扫描

    <context:component-scan base-package="indi.jaywee.controller"/>
    

配置 DispathcerServlet:在 web.xml

  • 关联核心配置文件

  • 启动时加载

  • 映射地址(类似 Java Web 中 Filter 的匹配规则)

    • 匹配形式:精确(/xxx)、后缀(*.xxx)、通配(/

    • 通常使用后缀匹配通配的形式

    • 不能使用 /*,否则会拦截返回的 JSP 视图。

      <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:spring-mvc.xml</param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
          <servlet-name>dispatcherServlet</servlet-name>
          <url-pattern>/</url-pattern>
      </servlet-mapping>
      

2.2.3、Controller & JSP

  1. 创建 success.jsp 页面

  2. 创建 Controller:基于注解配置 Controller 和 URL 映射

    @Controller
    public class HelloController {
        @RequestMapping("/hello")
        public String hello() {
            System.out.println("hello");
            return "success.jsp";
        }
    }
    
  3. 测试

    image-20220326193503105

2.2.4、报错 4xx 或 5xx(❗)

若所有步骤都正确,但是报错 4xx 或 5xx,检查 Tomcat 打包路径。

  1. 项目结构 → Artifacts → 当前模块 → WEB-INF

  2. 查看有无 lib 目录,没有则手动创建并添加 jar 包

    image-20220326192819857

3、Spring MVC 原理

3.1、@RequestMapping

作用:建立请求的 URL 与处理器之间的映射关系。

3.1.1、使用位置

两级目录共同组成请求 URL 的虚拟路径

  • 类上:请求 URL 的第一级访问目录(可选)
  • 方法上:请求 URL 的第二级访问目录

示例:访问 URL 为 http://localhost:8080/上下文路径/user/add

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/add")
    public void addUser(User user) {...}
}	

3.1.2、常用属性

  • value:指定请求 URL

  • method:指定请求方式(可选,不指定则任何请求方式都可访问)

    • RequestMethod 枚举类中封装了可指定的请求方式类型。

      image-20220326212212804

    • 可使用具体请求方式的注解:@GetMapping@PostMapping 等(本质也是 @RequestMapping

      image-20220326212434361

示例

  1. 任意请求方式

    // 任意请求方式
    @RequestMapping("/add")
    public void addUser(User user) {...}
    // 相当于
    @RequestMapping(value = "/add")
    public void addUser(User user) {...}
    
  2. 指定请求方式

    // 指定请求方式
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public void addUser(User user) {...}
    // 相当于
    @GetMapping("/add")
    public void addUser(User user) {...}
    

3.2、执行流程(❗)

3.2.1、组件

整个执行流程中,主要涉及以下组件。

含义 功能 说明
DispatcherServlet 前端控制器 拦截前端请求,调度各组件 相当于 MVC 中的 C
HandlerMapping 处理器映射器 负责解析请求所对应的处理器,返回处理器执行链 根据 XML 配置或注解进行解析查找
HandlerExecutionChain 处理器执行链 包含处理器对象和处理器拦截器 责任链模式(类似 Filter 中的过滤器链)
HandlerAdapter 处理器适配器 调度具体的处理器 适配器
Handler 处理器 真正处理具体请求,响应 ModelAndView 即 Controller,也称后端控制器
ModelAndView 模型视图 封装了数据和视图
ViewResolver 视图解析器 根据 ModelAndView,解析视图对象

3.2.2、流程图

Tomcat 引擎接收客户端请求,封装 request 和 response 对象

DispatcherServlet 的执行操作:

  1. 调用 HandlerMapping 解析请求对应的资源,获得 HandlerExecutionChain

  2. 调用 HandlerAdapter,将请求调度给具体的 Handler 处理,获得 ModelAndView

  3. 调用 ViewResolver解析ModelAndView 得到 View

  4. 渲染视图,向客户端发送响应

    image-20220326204633891

3.3、组件配置

  1. 在 SpringMVC 中,DispatcherServlet 配置了默认组件。
  2. 运用了 策略模式,各个组件可以相互替换。

3.3.1、默认组件

查看 spring-webmvc.jar 源码中的 DispatcherServlet.properties

image-20220327003815729

3.3.2、视图解析器

InternalResourceViewResolver (默认视图解析器)

有参构造方法:调用了父类的 setPrefix()setSuffix()

image-20220327004551242

父类 UrlBasedViewResolver

  • 属性

    • 请求和重定向前缀:用于判断 controller 指定跳转的视图名中,是否指定请求或重定向类型

    • URL 前缀和后缀:默认为空串,支持自定义

      public static final String REDIRECT_URL_PREFIX = "redirect:";
      public static final String FORWARD_URL_PREFIX = "forward:";
      private String prefix = "";
      private String suffix = "";
      
  • 方法(针对以上 4 个属性,其它的不作展示)

    • createView():判断视图名中是否指定请求或重定向类型,创建相应的 URL。
    • setPrefix()setSuffix():根据 SpringMVC 核心配置文件的配置,设置指定的前缀和后缀。

3.3.3、自定义视图前后缀

在(前后端不分离)开发中,很少修改其它组件配置(使用默认的即可)。

通常会配置视图解析器。

  • spring-mvc.xml 中配置视图解析器,自定义前后缀。

  • controller 在指定视图名时,视图解析器会自动拼接指定的前后缀。

  • prefix 值的前面必须加 /,否则报错。

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/前缀"/>
        <property name="suffix" value="后缀"/>
    </bean>
    

示例

指定拼接方式/user/视图名.jsp

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/user/"/>
    <property name="suffix" value=".jsp"/>
</bean>

Controller:返回的视图只需指定页面名称,无需编写前后缀

@Controller
public class RouterController {
    @RequestMapping("/toLogin")
    public String toLogin() {
        return "login";
    }
    @RequestMapping("/toRegister")
    public String toRegister() {
        return "register";
    }
}

image-20220327014103556

posted @ 2021-08-10 15:29  Jaywee  阅读(110)  评论(0编辑  收藏  举报

👇