初识SpringMVC【第一章】

  • ​🤪个人主页i笨笨i
  • 🐽版权:本文由【i笨笨i】原创,需要转载联系博主
  • 🎉欢迎关注、点赞、收藏(一键三连)和订阅专栏哦!

SpringMVC

一、SpringMVC介绍

1.1、回顾MVC三层架构


​ 模型一般由实现JavaBean,javaBean分为实体Bean和业务Bean,业务Bean包含了业务逻辑类和数据访问类。展示层包含控制器和视图。

展示层:jsp+servlet,SpringMVC;业务逻辑层:JavaBean和Spring;数据访问层:jdbc、springjdbc、MyBatis;

控制器:servlet、SpringMVC

分层、解耦、责任分明化;

1.2、介绍

​ SpringMVC是Spring框架的一部分,是基于Java实现的轻量级Web框架。学习SpringMVC框架最核心的就是DispatcherServlet的设计,掌握好DispatcherServlet是掌握SpringMVC的核心关键。

1.3、SpringMVC优点

  • 轻量级,可适配,非侵入
  • 高效,基于请求响应的MVC框架(解耦、可重用、提高维护性)
  • 与Spring兼容好
  • 约定优于配置
  • 功能强大:灵活的URL映射,RESTful、数据验证、格式化、本地化、主题标签库等
  • 简洁灵活

1.4、SpringMVC的实现原理

​ Spring的Web框架围绕==DispatcherServlet(前端控制器)==设计。DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始,使用java 5 或者以上版本用户可以采用基于注解的controller声明方式。

​ SpringMVC框架像许多其他MVC框架一样,以请求为驱动,围绕一个中心Servlet分派请求及提供其他功能,DispatcherServlet是一个实际的Servlet(它继承自HttpServlet基类)。

Snipaste_2022-08-25_10-00-01

SpringMVC的具体执行流程:

​ 当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,再创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。

Snipaste_2022-08-25_10-25-30

二、SpringMVC入门案例

2.1、基于注解的SpringMVC

1️⃣使用SpringMVC技术需要先导入SpringMVC坐标与Servlet坐标

<dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope><!-- Tomcat内置了servlet所以这里设置了范围 -->
</dependency>

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

2️⃣创建SpringMVC控制器类(等同于Servlet功能)处理请求

package com.item.controller;
//2.定义Controller
//2.1使用@Controller来定义bean
@Controller
public class UserController {
    //2.2设置当前操作的访问路径
    @RequestMapping("/save")
    //2.3设置当前操作的返回值类型
    @ResponseBody//将返回值作为一个整体给外部
    public String save(){
        System.out.println("user save ...");
        return "{'module':'springmvc'}";
    }
}

3️⃣初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对应的bean

package com.item.config;
@Configuration
@ComponentScan("com.item.controller")
public class SpringMvcConfig {
}

4️⃣初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求

package com.item.config;
//4. 定义一个servlet容器启动的配置类,在里面加载Spring的配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    /**
     * 加载springMVC容器配置
     * @return
     */
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
    
    /**
     * 设置哪些请求归属springMVC处理
     * @return
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};// "/"表示所以请求
    }

    /**
     * 加载Spring容器配置
     * @return
     */
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        /*加载Spring容器配置,SpringConfig类为Spring配置类
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringConfig.class);
        return ctx;
        */
        return null;
    }
}
  • 简化开发

AbstractAnnotationConfigDispatcherServletInitializerAbstractDispatcherServletInitializer的子类。

public class ServletContainersInitConfig 
    			extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

5️⃣在IDEA中启动Tomcat

  • 导入插件(pom.xml内)
<build>
    <plugins>
      <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>
  • 方式一

点击 Add Configuration

点击加号再找到Maven(此项目用Maven构建)。

再Run框内输入tomcat7:run,即可点击apply,ok

  • 方式二

Snipaste_2022-08-22_15-24-29

导入插件后,可以通过快捷方式运行,在程序区右击如何选择Run Maven,再选择tomcat7:run

2.1.1、相关注解介绍

名称:@Controller

类型:类注解

位置:SpringMVC控制器类定义上方

作用:设定SpringMVC的核心控制器bean

  • 范例
@Controller
public class UserController {
}

名称:@RequestMapping

类型:方法注解

位置:SpringMVC控制器方法定义上方

作用:设置当前控制器方法请求访问路径

  • 范例
@RequestMapping("/save")
public void save(){
	System.out.println("user save ...");
}
  • 相关属性
    • value(默认):请求访问路径

名称:@RequestMapping

类型:方法注解

位置:SpringMVC控制器方法定义上方

作用:设置当前控制器方法响应内容为当前返回值,无需解析

  • 范例
@RequestMapping("/save")
@ResponseBody
public String save(){
	System.out.println("user save ...");
	return "{'module':'springmvc'}";
}
2.1.2、总结
  • SpringMVC入门程序开发总结(1+N)

    • 一次性工作
      • 创建工程、设置服务器、加载工程
      • 导入坐标
      • 创建web容器启动类,加载SpringMVC配置,并设置SpringMVC请求拦截路径
      • SpringMVC核心配置类(设置配置类,扫描controller包,加载controller控制器bean)
    • 多次工作
      • 定义处理请求的控制器类
      • 定义处理请求的控制器类方法,并配置映射路径(@RequestMapping)与返回json数据(@ResponseBody)
  • AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类

  • AbstractDispatcherServletInitializer提供三个接口方法供用户实现

    • createServletApplicationContext方法,创建Servlet容器时,加载SpringMVC对应的bean并放入WebApplicationContext对象范围中,而WebApplicationContext的作用范围为ServletContext范围,即整个web容器范围。
    • getServletMappings方法,设定SpringMVC对应的请求映射路径,设置为/表示拦截所以请求,任意请求都转入到SpringMVC进行处理。
    • createRootApplicationContext方法,如果创建Servlet容器时需要加载非SpringMVC对应的bean,使用当前方法进行,使用方式同createServletApplicationContext
    public class ServletContainersInitConfig 
        				extends AbstractDispatcherServletInitializer {
        /**
         * 加载springMVC容器配置
         * @return
         */
        @Override
        protected WebApplicationContext createServletApplicationContext() {
            AnnotationConfigWebApplicationContext ctx = 
                			new AnnotationConfigWebApplicationContext();
            ctx.register(SpringMvcConfig.class);
            return ctx;
        }
    
        /**
         * 设置哪些请求归属springMVC处理
         * @return
         */
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};// "/"表示所以请求
        }
    
        /**
         * 加载Spring容器配置
         * @return
         */
        @Override
        protected WebApplicationContext createRootApplicationContext() {return null;
        }
    }
    
2.1.3、入门案例工作流程分析
  • 启动服务器初始化过程
    1. 服务器启动,执行ServletContainersInitConfig类,初始化web容器
    2. 执行createServletApplicationContext方法,创建了WebApplicationContext对象
    3. 加载SpringMvcConfig(SpringMVC配置类)
    4. 执行@ComponentScan加载对应的bean
    5. 加载UserController,每个@RequestMapping的名称对应一个具体的方法
    6. 执行getServletMappings方法,定义所有的请求都通过SpringMVC
  • 单次请求过程(返回json数据等)
    1. 发送请求localhost/save
    2. web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理
    3. 解析请求路径 /save
    4. 由 /save 匹配执行对应的方法 save()
    5. 执行 save()
    6. 检测到有@ResponseBody直接将 save()方法的返回值作为响应请求体返回给请求方

工作流程

  1. DispatcherServlet表示前端控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
  2. HanderMapping为处理器映射。DispatcherServlet调用HanderMapping,HanderMapping根据请求URL查找Hander(处理器)。
  3. 返回处理执行链,根据URL查找控制器,并且将解析后的信息转递给DispatcherServlet
  4. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
  5. 执行handler找到具体的处理器
  6. Controller将具体的执行信息返回给HandlerAdapter,如ModuleAndView
  7. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet
  8. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑名。
  9. 视图解析器将解析的逻辑视图名传给DispatcherServlet。
  10. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图,进行渲染。
  11. 将响应数据返回给客户端。

简单版的流程

  1. 用户发出请求

  2. 由Tomcat接收到对应的请求

  3. SpringMVC的DispatcherServlet(前端控制器)接收到所有请求

  4. 查看请求地址和@RequestMapping注解的哪个匹配,来找到具体的类的处理方法

  5. 前端控制器找到目标处理类和方法之后,执行目标方法

  6. 方法执行完毕之后会有一个返回值,SpringMVC会将这个返回值用视图解析器进行解析拼接成完整的页面地址

  7. DispatcherServlet拿到页面地址之后,转发到具体的页面

2.1.4、Controller加载控制与业务bean加载控制
  • SpringMVC相关bean(表现层bean)
  • Spring控制的bean
    • 业务bean(Service)
    • 功能bean(DataSource等)

❓因为功能不同,如何避免Spring错误的加载到SpringMVC的bean?

解决方案:加载Spring控制的bean的时候排除掉SpringMVC控制的bean。

  • SpringMVC相关bean加载控制
    • SpringMVC加载的bean对应的包均在com.item.controller包内
  • Spring相关bean加载控制
    • 方式一:Spring加载的bean设定扫描范围为com.item,排除掉controller包内的bean
    • 方式二:Spring加载的bean设定扫描范围为精准范围,例如service包,dao包等
    • 方式三:不区分Spring与SpringMVC的环境,加载到同一个环境中
//方式一
@ComponentScan({"com.item.dao","com.item.service"})

//方式二
@ComponentScan(value = "com.item",
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.ANNOTATION,
        classes = Controller.class
    )
)

注意:SpringMvcConfig和SpringConfig配置类在com.item.config包内

​ 如果使用第二种方式排除,则必须将SpringMvcConfig类上的@Configuration注解去掉,因为方式二中只排除了Controller注解但没有排除@Configuration注解,并且@Configuration注解是将类注册为配置类,所以会将SpringMvcConfig类中配置的@ComponentScan路径进行扫描并进行注册bean。

​ 解决方法:可以将SpringMvcConfig和SpringConfig配置类放到com包下或其他位置。

名称:@ComponentScan

类型:类注解

  • 范例:
@Configuration
//@ComponentScan({"com.item.dao","com.item.service"})
@ComponentScan(value = "com.item",
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.ANNOTATION,
        classes = Controller.class
    )
)
public class SpringConfig {
}

属性:

  • excludeFilters:排除扫描路径中的加载的bean,需要指定类别(type)与具体项(classes)
  • includeFilters:加载指定的bean,需要指定类别(type)与具体项(classes)

2.2、基于XML的SpringMVC

  • 使用IDEA创建空的Maven项目

Snipaste_2022-08-25_12-31-23

  • 要创建Web项目,添加web目录

右击项目名(springmvc01),找到Add Framework Support,找到WebApplication勾选即可,可选择版本。

Snipaste_2022-08-25_12-33-40

Snipaste_2022-08-25_12-37-49

  • 配置Tomcat

点击右上角的 Add Configuration。

Snipaste_2022-08-25_12-40-23

点击加号,找到Tomcat Server,点击Local,选择Deployment,点击加号,选择Artifacts。

Snipaste_2022-08-25_11-40-40

Snipaste_2022-08-25_12-45-47

选中添加的Artifacts,修改Application context,修改成项目名(从属性是访问的路径)。

Snipaste_2022-08-25_12-46-05

如果遇到报错,可能是out下WEB-INF的lib没有SpringMVC相关jar包,导入即可。

点击File选择ProjectStructure,点击Artifacts的加号,选择Web Application:Exploded的FromModules即可。

Snipaste_2022-08-25_11-46-59

选择WEB-INF文件右击创建文件夹,选中右边项目名下的所有jar包,右击选择Put into /WEB-INF/lib。再点击aplly。

Snipaste_2022-08-25_12-24-41

Snipaste_2022-08-25_12-25-25

Snipaste_2022-08-25_12-25-45

2.2.1、添加依赖pom.xml
<!-- SpringMVC坐标 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>
2.2.2、编写web.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
        接收除了.jsp的请求都交给SpringMVC去处理
     -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 初始化参数
        contextConfigLocation 配置SpringMVC的xml配置文件,指定路径
        也可以不配置:会自动去WEB-INF去找一个名字叫 [servlet-name]-servlet.xml(springmvc-servlet.xml)文件
         -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>

        <!-- 启动服务器时加载servlet
         当web服务器启动时就会创建servlet(会自动调用servlet的构造函数及init()方法)
         init()方法内加载springmvc配置文件
         -->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- 配置DispatcherServlet映射
    通常会为SpringMVC映射的路径为:/*,/,*.do,*.action,/request/*
    /:除了.jsp的请求都会被拦截
    /*:所有请求都会被拦截
    *.do,*.action:URL结尾以.do或.action的请求会拦截
    -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- 配置拦截请求路径 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
2.2.3、编写springmvc需要的配置文件,spring-mvc.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 https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.item"/>
</beans>
2.2.4、HelloController类
package com.item.controllers;

@Controller
public class HelloController {
    /**
     * @RequestMapping将方法映射给对应的URL请求处理
     * @param name  SpringMVC的自动匹配
     * @return
     */
    @RequestMapping("/Hello")
    public String hello(String name){
        System.out.println("hello SpringMVC:"+name);
        /**
         * 响应
         * redirect:重定向
         * forward:转发(默认)return "index.jsp";
         */
        return "redirect:index.jsp";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值