SpringMVC学习之路

SpringMVC学习之路


本篇文章记录于尚硅谷学习!!!

一、SpringMVC简介

1.1 什么是MVC

MVC是一种软件架构的思想,将软件按照模型、视图、控制器划分

M:指的是Model层(模型层),指的是工程里的JavaBean。
JavaBean分两类:

  • 实体类Bean:存储业务数据
  • 业务处理Bean:Service或者Dao对象

V: 视图层, 指的是前端显示界面,与用户交互的

C: Controller、控制层,指的是工程中的Servlet,作用是请求和响应服务器

MVC的工作流程:

用户通过视图层发送请求到服务器,服务器中的请求被Controller接收,C调用响应的Model层处理请求,将结果返回给C,然后C在将结果传给View层,进行渲染。

二、HolleWord

2.1 创建Maven工程,引入依赖

引入的依赖如下:

<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>


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

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.3.13</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.3.13</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.13</version>
    </dependency>


    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.3.13</version>
    </dependency>

2.2 配置web.xml

注意/与/*的区别
/:不匹配jsp
/*匹配所有文件

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <!--配置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>

    <!--将前端控制器DispatcherServlet的初始化时间提前到服务器的启动时间-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <!--注意/与/*的区别-->
    <!-- /:不匹配jsp。 /*匹配所有文件  -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

2.3 创建请求控制器

配置@Controller
在配置文件中配置包扫描注解

package com.jzq.mvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

// 通过注解标识 (bean)
@Controller
public class HelloController {

    @RequestMapping(value = "/")
    public String index() {
        // 返回视图的名称
        return "index";
    }


    @RequestMapping(value = "/page1")
    public String page1() {
        return "page1";
    }
}

配置文件

<?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="com.jzq.mvc.controller"></context:component-scan>

    <!--  配置视图解析器  -->
    <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <property name="order" value="1"></property>
        <property name="characterEncoding" value="UTF-8"></property>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                        <!--  视图前缀  -->
                        <property name="prefix" value="/WEB-INF/templates"></property>
                        <!--  视图后缀  -->
                        <property name="suffix" value=".html"></property>
                        <property name="templateMode" value="HTML 5"></property>
                        <property name="characterEncoding" value="UTF-8"></property>
                    </bean>
                </property>
            </bean>
        </property>

    </bean>
</beans>

三、@RequestMapping注解

3.1 @RequestMapping注解的功能

@RequestMapping的功能是将请求和处理请求的控制器方法关联起来,建立映射关系。

3.2 @RequestMapping注解的位置

  1. 标识一个类: 设置映射请求的请求路径的初始信息
  2. 表示一个方法: 色湖之映射请求的请求路径的具体信息

3.3 @RequestMapping注解的value属性

@RequestMapping注解的value属性是:请求地址匹配请求映射
@RequestMapping注解的value属性是:一个字符串类型的数组,表示该请求映射能够匹配的多个地址所对应的请求。
@RequestMapping注解的value属性必须设置。至少一个!

3.4 @RequestMapping注解的method属性

@RequestMapping注解的method: 通过请求的方式
@RequestMapping注解的method是一个RequestMethod类型的数组,也可以匹配多个请求。

@RequestMapping(value = {"/page1","/page2"}, method = {RequestMethod.GET, RequestMethod.POST})
    public String page1() {
        return "page1";
    }
  1. 对于处理指定的请求方式的控制器方法,SpringMVC提供了@RequestMapping的派生注解
    处理GET:@GetMapping
    处理POST:@PostMapping
    。。。
  2. 目前浏览器只支持,post,get。
    发送其他请求,例如put时, 需要通过Spring提供的过滤器HiddenHttpMethodFilter,在restful时。

3.5@RequestMapping注解的params属性

携带参数
“param”: 表示请求映射所匹配的params必须携带param请求参数
“!param”: 表示请求映射所匹配的params必须不能携带param请求参数
“param=value”: 表示请求映射所匹配的params必须携带param请求参数,并且等于value
“param!=value”: 表示请求映射所匹配的params必须携带param请求参数,但是不能等于value

@GetMapping
    @RequestMapping(value = {"/page1","/page2"}, params = "username!=12")
    public String page1() {
        return "page1";
    }

3.5@RequestMapping注解的headers属性

携带请求头
“header”: 表示请求映射所匹配必须携带header请求参数
“!header”: 表示请求映射所匹配必须不能携带header请求参数
“header=value”: 表示请求映射所匹配必须携带header请求参数,并且等于value
“header!=value”: 表示请求映射所匹配必须携带header请求参数,但是不能等于value
如果当前的@RequestMapping注解的满足value和method,但是不满足headers属性,此时页面报404,资源未找到!

3.6 SpringMVC支持ant风格的路径

? : 表示任意单个字符串
*:表示任意的0个或者多个字符
:表示任意的一层或多层目录
注意 使用
时,只能用/**/xxx的方式

3.7 SpringMVC支持路径中的占位符

原始方式:/add?user=123
restful: /add/123
SpringMVC路径中的占位符经常用于restful风格中,通过 占位符{xxx} 占位,表示传输的数据,再通过@PathVariable注解,将占位符表示的数据赋值给控制器方法的形参。

@GetMapping
    @RequestMapping(value = {"/page1","/page2/{id}"})
    public String page1(@PathVariable("id") String id) {
        System.out.println("id:"+id);
        return "page1";
    }

四、SpringMVC获取请求参数

4.1 通过ServletAPI获取

@RequestMapping("/param")
    public String param(HttpServletRequest httpServletRequest) {
        System.out.println(httpServletRequest.getParameter("name"));
        return "param";
    }

4.2 通过控制器方法的形参获取请求参数

在控制器方法中设置和请求参数同名的形参,当浏览器发送请求的时候,匹配到请求映射时,在DispatcherServlet中就将会将请求参数赋值给相应的形参。

@RequestMapping("/param2")
    public String param2(String name) {
        System.out.println(name);
        return "param";
    }

4.3 @RequestParam

此注解一共三个属性
value: 指定形参赋值时请求参数名。
required:设置是否必须传送该请求参数, 默认为true,必须传送,不传报400。
defaulValue:不管是否设置了required,当value没传送时,默认为这个值。

4.4 @RequestHeader

该注解是将请求头信息和控制器方法的形参创建映射关系。 (获取token)
属性同 @RequestParam的一致。

4.5 @CookieValue

该注解是将cookie和控制器方法的形参创建映射关系。
属性同 @RequestParam的一致。

4.6 获取参数直接为实体类

传的参数名字一致的和控制器方法的实体类参数名一样的进行映射。

@RequestMapping("/param3")
    public String param3(
            User user
    ) {
        System.out.println(user);
        return "param";
    }

五、域对象共享数据

5.1 使用servletAPI向request域对象共享数据

@RequestMapping("/param")
    public String param(HttpServletRequest httpServletRequest) {
        System.out.println(httpServletRequest.getParameter("name"));
        httpServletRequest.setAttribute("name", httpServletRequest.getParameter("name"));
        return "param";
    }

5.2 使用ModelAndView向request域对象共享数据

ModelAndView 包括了 Model: 数据 , View: 视图
addObject(“健”, “值”) 设置数据
setviewName(“页面”) 设置请求页面

@RequestMapping("/param4")
    public ModelAndView param3(@RequestParam("name") String name) {
        /**
         * ModelAndView 包括了 Model: 数据 , View: 视图
         * addObject("健", "值") 设置数据
         * setviewName("页面") 设置请求页面
         */

        ModelAndView mav = new ModelAndView();
        mav.addObject("name", name);
        mav.setViewName("param");

        return mav;
    }

5.3 使用Model向request域对象共享数据

@RequestMapping("/param5")
    public String param5(Model model, @RequestParam("name") String name) {
        model.addAttribute("name", name);
        return "param";
    }

5.4 使用map向request域对象共享数据

@RequestMapping("/param6")
    public String param6(Map<String, Object> map, @RequestParam("name") String name) {
        map.put("name", name);
        return "param";
    }

5.5 使用ModelMap向request域对象共享数据

@RequestMapping("/param7")
    public String param7(ModelMap modelMap, @RequestParam("name") String name) {
        modelMap.addAttribute("name", name);
        return "param";
    }

5.6 向session域共享数据

@RequestMapping("/param8")
    public String param8(HttpSession httpSession, @RequestParam("name") String name) {
        httpSession.setAttribute("name", name);
        return "param";
    }

5.7 向application域共享数据

@RequestMapping("/param9")
    public String param9(HttpSession httpSession, @RequestParam("name") String name) {
        ServletContext application = httpSession.getServletContext();
        application.setAttribute("name", name);
        return "param";
    }

六、 SpringMVC的视图

6.1 转发视图

⭐ 请求的视图

此时的请求带了参数: httpServletRequest.setAttribute(“name”, “大傻子”);

@GetMapping
    @RequestMapping(value = {"/page1","/page2/{id}"})
    public String page1(HttpServletRequest httpServletRequest) {
        //System.out.println("id:"+id);
        httpServletRequest.setAttribute("name", "大傻子");
        return "forward:/api/param";
    }

⭐ 被转发的视图

转发的视图通过httpServletRequest.getAttribute(“name”)能够取到数据

@RequestMapping("/param")
    public String param(HttpServletRequest httpServletRequest) {
        System.out.println(httpServletRequest.getAttribute("name"));
        httpServletRequest.setAttribute("name", httpServletRequest.getAttribute("name"));
        return "param";
    }

6.2 重定向视图

SpringMVC中默认的重定向视图为 RedirectView
当控制器方法中设置的视图名称为"redirect:"为前缀的时候,创建RedirectView视图,此时的视图名称不会被SpringMVC配置文件中配置的视图解析器解析,而是将前缀"redirect:"去掉,剩余的部分作为路径通过重定向的方式实现跳转
⭐ 请求的视图
此时的请求带了参数: httpServletRequest.setAttribute(“name”, “大傻子”);

@GetMapping
    @RequestMapping(value = {"/page1","/page2/{id}"})
    public String page1(HttpServletRequest httpServletRequest) {
        //System.out.println("id:"+id);
        httpServletRequest.setAttribute("name", "大傻子");
        return "redirect:/api/param";
    }

⭐ 重定向的视图

重定向的视图是一个新的请求,由服务器发出,取不到数据

@RequestMapping("/param")
    public String param(HttpServletRequest httpServletRequest) {
        System.out.println(httpServletRequest.getAttribute("name"));
        httpServletRequest.setAttribute("name", httpServletRequest.getAttribute("name"));
        return "param";
    }

6.3 视图控制器view-controller

当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理器方法使用view-controller标签进行表示
path : 设置处理的请求地址
view-name: 设置请求地址所对应的视图名称

⭐在springMVC.xml中配置

<!--  配置视图控制器  -->
    <mvc:view-controller path="/" view-name="index"></mvc:view-controller>

⭐设置mvc注解驱动的标签(在springMVC.xml中配置)

⭐ 当SpringMVC中设置任何一个view-controller时,其他的控制器的请求映射将全部失效,此时需要在SpringMVC的核心配置文件中设置mvc注解驱动的标签

<!--  开启MVC的注解驱动  -->
    <mvc:annotation-driven/>

七、 RESTFul请求 和静态资源处理

7.1 HiddenHttpMethodFilter

由于浏览器只发送get和post请求。
SpringMVC提供了HiddenHttpMethodFilter帮助我们将POST转换成DELETE或PUT请求。
处理条件: 1. 当前请求方式必须为post, 当前请求必须传送亲求参数_method
(⭐)当然这不包括ajax,只是页面请求的form

<from method="post" action="路径">
	!!!必须包括
	<input type="hidden" name="_method" value="PUT">
</from>

⭐ 处理put或者delete的xml配置

加入有编码过滤器,一定放在编码过滤器的下面

 <!-- 配置HiddenHttpMethodFilter -->
  <filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

7.2 静态资源处理

开启对静态资源的访问,<mvc:default-servlet-handler/>
注意必须和MVC的注解驱动一块使用

 <!--开放对静态资源的访问-->
    <mvc:default-servlet-handler/>

    <!--  开启MVC的注解驱动  -->
    <mvc:annotation-driven/>

八、 HttpMessageConverter

HttpMessageConverter, 报文信息转换器, 将请求报文转换为java对象,或将java对象转化为响应报文。
HttpMessageConverter提供了两个注解和两个类型: @RequestBody,@ResponseBody,RquestEntity,ResponseEntity

8.1 @RequestBody

@RequestBody可以获取请求体,需要在控制器方法设置一个形参,使用@RequestBody进行标识,当前请求的请求体就会为当前所标识的形参赋值

 @RequestMapping(value = {"/requestbody"})
    public String page2(@RequestBody String requestBody) {
        System.out.println("requestBody:"+requestBody);
        return "page1";
    }

8.2 RequestEntity

RequestEntity封装请求报文的一种类型,需要在控制器方法的形参中设置该类型的形参,当前请求的请求报文就慧赋值给该形参,通过getHeaders()获取请求头信息,通过getBody()获取请体信息。

@RequestMapping(value = {"/requestbody2"})
    public String page3(RequestEntity<String> requestEntity) {
        System.out.println("requestH:"+requestEntity.getHeaders());
        System.out.println("requestB:"+requestEntity.getBody());
        return "page1";
    }

8.3 @ResponseBody(最常用)

@ResponseBody用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器

 @RequestMapping(value = {"/requestbody3"})
    @ResponseBody
    public String page4() {
        return "page1";
    }

页面结果显示: page1

8.4 @ResponseBody响应json(SpringMVC处理)

@ResponseBody处理json的步骤:

  1. 添加jackson依赖
<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.12.1</version>
</dependency>
  1. 在SpringMVC的核心配置文件中开启mvc的注解驱动,此时在HandlerAdaptor中会自动装配一个消息转换器:Mappinggiackson2HttpMessageConverter,可以将响应到浏览器的Java对象转换成json格式的字符串
<!--  开启MVC的注解驱动  -->
    <mvc:annotation-driven/>
  1. 在处理器方法上使用@ResponseBody注解
  2. 将java对象直接作为控制器方法的返回值进行返回,就会自动转换为json格式的字符串
@RequestMapping(value = {"/requestbody4"})
    @ResponseBody
    public User page5() {
        return new User("急啊急啊就", "dasa", 15);
    }

8.5 @RestController注解

@RestController注解 是SpringMVC提供的一个复合注解,标识在控制器的类上,就相当于为类添加了@Controller注解,并且为其中的每个方法添加了@ResponseBody注解

8.6 ResponseEntity

ResponseEntity用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文。

九、文件下载

有一点问题的代码,后期解决,postman的时候打不通

在springMVC的配置文件内配置文件上传解析器

<!--  配置文件上传解析器,将上传的文件封装成MultipartFile  -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

只在配置文件配置往往找不到bean, 需要配置jar, 在pom中引入commons-fileuploa

<dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>

代码逻辑

@RequestMapping("/upload")
    @PostMapping
    @ResponseBody
    public Map<String, String> upload(MultipartFile multipartFile, HttpSession httpSession) throws IOException {
        // 获取文件的名字
        System.out.println("这是说的啥好的稍等哈是");

        // 这里有问题,postman跑不动
        String fileName = multipartFile.getOriginalFilename();
        System.out.println("ffffffffffffff"+fileName);

        // 获取项目路径
        ServletContext servletContext = httpSession.getServletContext();
        String photoPath = servletContext.getRealPath("photo");

        File file = new File(photoPath);
        // 判断是否存在路径
        if(!file.exists()) {
            // 路径不存在,创建路径
            file.mkdir();
        }

        // 最终文件保存路径(文件路 + 文件分隔符/(linux)或者\(win) + 文件名)
        String finalPath = photoPath + File.separator + fileName;
        multipartFile.transferTo(new File(finalPath));


        Map<String, String> result = new HashMap<>();
        result.put("msg", "添加成功");
        result.put("data", finalPath);
        return result;
    }

十、 拦截器

10.1 拦截器配置

SpringMVC 中的拦截器用于拦截控制器方法的执行
SpringMVC 中的拦截器需要实现HandlerInterceptor或者是继承HandlerInterceptorAdapter类(过时)
SpringMVC 的拦截器必须在SpringMVC的配置文件中配置

⭐所有请求都会被拦截

<!--  配置拦截器  -->
    <mvc:interceptors>
        <!--<bean class="com.jzq.mvc.interceptors.FirstInterceptors"></bean>-->
        <ref bean="firstInterceptors"/>
    </mvc:interceptors>

⭐ 指定拦截器
<mvc:mapping> : 设置被拦截的请求
<mvc:exclude-mapping: 设置不需要被拦截得路由

<!--  配置拦截器(配置请求)  -->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--  /* 标识一级目录   /** 标识多级目录 -->
            <mvc:mapping path="/*"/>

            <!--   不被拦截得路由  -->
            <mvc:exclude-mapping path="/index"/>
            <ref bean="firstInterceptors"/>
        </mvc:interceptor>
    </mvc:interceptors>

10.2 拦截器的三个抽象方法

SpringMVC中的拦截器有三个抽象方法:
preHandle: 控制器方法执行之前执行preHandle(), 其中boolean类型的返回值表示拦截或者放行,true:放行;false:拦截(不调用控制器方法)。
postHandle:控制器方法执行之后执行postHandle()
afterCompletion: 处理完视图和模型数据,渲染视图完毕之后执行afterCompletion()

package com.jzq.mvc.interceptors;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FirstInterceptors implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");

    }
}

10.3 多个拦截器的执行顺序

⭐如果每个拦截器的preHandle()都返回true;

此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关。
preHandle()会按照配置的顺序执行,而postHandle()和afterComplation()会按照配置的反顺序执行。

⭐如果每个拦截器的preHandle()都返回false;

preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回fasle的拦截器之前的拦截器的afterComplation()会执行。

十一、异常处理器

11.1 基于配置的异常处理

SpringMVC提供了一个处理控制器方法执行过程中出现的异常的接口:HandlerExceptionResover。
HandlerExceptionResover的实现类有DefaultHandlerExceptionResover和SimpleMappingExceptionResover

⭐SimpleMappingExceptionResover的使用方式:

<!--  配置异常处理  -->
   <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
       <property name="exceptionMappings">
           <props>
               <!--
                   properties的健表示处理器方法执行过程中出现的异常
                   properties的值表示若出现指定异常时,设置一个新的视图名称(被视图解析器解析),跳转到指定界面
               -->
               <prop key="java.lang.ArithmeticException">error</prop>
           </props>
       </property>
       <!--  设置将异常信息共享在请求域(可以取到)  -->
       <property name="exceptionAttribute" value="ex"></property>
   </bean>

11.2 基于注解的异常处理

@ControllerAdvice标识类
@ExceptionHandler(value = {ArithmeticException.class, NullPointerException.class}):标识方法,传入异常类,在方法中写处理逻辑
可以通过参数Exception ex获取异常信息,在携带信息(这里用的Model)给转发界面

package com.jzq.mvc.controller;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class ExceptionController {
    @ExceptionHandler(value = {ArithmeticException.class, NullPointerException.class})
    public String testException(Exception ex, Model model){
        model.addAttribute("ex", ex);
        return "error";
    }
}

十二、 注解配置SpringMVC

12.1 创建初始化类, 代替web.xml

在这里插入图片描述

getRootConfigClasses : 指定spring的配置类
getServletConfigClasses: 指定SpringMVC的配置类
getServletMappings: 指定DispatcherServlet的映射规则,即url-pattern
getServletFilters: 注册过滤器

package com.jzq.mvc.config;


import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.Filter;


// web工程的初始化类,用来代替web.xml
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     * 指定spring的配置类
     * @return
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    /**
     * 指定SpringMVC的配置类
     * @return
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    /**
     * 指定DispatcherServlet的映射规则,即url-pattern
     * @return
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     * 注册过滤器
     * @return
     */
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceResponseEncoding(true);
        // 配置HiddenHttpMethodFilter
        HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
        return new Filter[] {characterEncodingFilter, hiddenHttpMethodFilter};
    }
}

12.2 代替SpringMCV.xml的配置类

分别代替的方法如下java

  1. 扫描组件
  2. 视图解析器
  3. view-controller
  4. default-servlet-handler
  5. mvc注解驱动
  6. 文件上传解析器
  7. 异常处理
  8. 拦截器
package com.jzq.mvc.config;

import com.jzq.mvc.interceptors.FirstInterceptors;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import java.util.List;
import java.util.Properties;

/**
 *  代替SpringMVC的配置文件
 *   1. 扫描组件
 *   2. 视图解析器
 *   3. view-controller
 *   4. default-servlet-handler
 *   5. mvc注解驱动
 *   6. 文件上传解析器
 *   7. 异常处理
 *   8. 拦截器
 */

// 将当前类标识为配置类
@Configuration
// 1.扫描组件
@ComponentScan("com.jzq.mvc.controller")
//  5. mvc注解驱动
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    //3. view-controller


    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/index").setViewName("index");
    }

    // 4. default-servlet-handler
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    // 6. 文件上传解析器
    @Bean
    public MultipartResolver multipartResolver(){
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
        return commonsMultipartResolver;
    }

    // 7. 异常处理


    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
        Properties properties = new Properties();

        /**
         * 键是 异常类型
         * 值是 页面名
         */
        properties.setProperty("java.lang.ArithmeticException", "error");
        simpleMappingExceptionResolver.setExceptionMappings(properties);
        simpleMappingExceptionResolver.setExceptionAttribute("exception");
        resolvers.add(simpleMappingExceptionResolver);
    }

    // 8. 拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器并设置路径
        FirstInterceptors firstInterceptors = new FirstInterceptors();
        registry.addInterceptor(firstInterceptors).addPathPatterns("/**");
    }
}

十三、SpringMVC执行流程

13.1 SpringMVC常用组件

在这里插入图片描述

13.2 DispatcherServlet初始化过程

DispatcherServlet本质就是一个Servlet,所以天然的遵守Servlet的生命周期。所以宏观上是Servlet的生命周期来调度。

⭐ 步骤流程
在这里插入图片描述

⭐ a. 初始化 WebApplicationContext

⭐ b. 创建 WebApplicationContext

在这里插入图片描述

⭐ c. DispatherServlet初始化策略

FrameworkServlet创建WebApplicationContext后,刷新容器,调用onRefresh(wac), 此方法在DispatherServlet中进行了重写,调用了initStrategies(ApplicationContext context),初始化策略,即初始DispatherServlet的各个组件

所在类为org.springframework.web.servlet.DispatherServlet

protected void initStrategies(ApplicationContext context) {
        this.initMultipartResolver(context);
        this.initLocaleResolver(context);
        this.initThemeResolver(context);
        this.initHandlerMappings(context);
        this.initHandlerAdapters(context);
        this.initHandlerExceptionResolvers(context);
        this.initRequestToViewNameTranslator(context);
        this.initViewResolvers(context);
        this.initFlashMapManager(context);
    }

13.3 DispatcherServlet调用组件处理请求

⭐ a. processRequest()

FrameworkServlet重写HtppSrvlet中的service()和doXXX(), 这些方法中调用了processRequest(request, response)

所在类 org.springframework.web.servlet.FrameworkServlet

⭐ b. doService()

所在类 org.springframework.web.servlet.DispatcherServlet

⭐ c. doDispatch()

所在类 org.springframework.web.servlet.DispatcherServlet

13.4 SpringMVC的执行流程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值