【基础知识】_SpringMVC

SpringMVC

Spring集成web环境

应用上下文对象ApplicationContext是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的,但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) ,这样的弊端是配置文件加载多次,应用上下文对象创建多次。

在Web项目中,可以使用ServletContextListener监听Web应用的启动,我们可以在Web应用启动时,就加载Spring的配置文件,创建应用上下文对象ApplicationContext,在将其存储到最大的域servletContext域中,这样就可以在任意位置从域中获得应用上下文ApplicationContext对象了。

上面的分析不用手动实现, Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获得应用上下文对象。

获取Spring框架创建的应用上下文对象的基本步骤

  1. 在pom.xml文件中导入Spring集成web的坐标

  2. 在web.xml文件中配置ComtextLoaderListener监听器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!--全局初始化参数,用于参数化配置监听器中所要加载的Spring配置文件,这样以后如果要改变要读取的Spring配置文件,在此处改动就可以-->
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <!--配置web项目的监听器,此处选用Spring-web包中的-->
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
  3. 在java组件中通过工具获取应用上下文对象

    1
    2
    3
    4
    5
    6
    7
    8
    //获取ServletContext域对象。
    ServletContext servletContext = request.getServletContext();

    //使用Spring-web框架中的工具类获取ServletContext域中的应用上下文对象。
    ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);

    UserService userService = (UserService) app.getBean("userService");
    userService.save();

SpringMVC简介

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架 。

MVC分别是指:

  • modul(模型):用于数据封装和业务逻辑处理
  • view(视图):用于数据的展示
  • controller(控制器):用于分发指派工作

传统的web层Servlet类要继承和实现特定接口,才可以接收客户端发出的请求消息并回复响应消息。而SpringMVC可以通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口,这套注解正是mvc框架崛起的主要因素。

SpringMVC使用步骤

  1. 在pom.xml文件中导入Spring和SpringMVC的坐标

  2. 在pom.xml文件中导入Servlet和Jsp的坐标

  3. 在web.xml文件中配置SpringMVC的核心控制器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <!--配置SpringMVC的前端控制器-->
    <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <!--servlet初始化参数:通过给前端控制器加载初始配置文件来告诉前端控制器它所要控制的Controller在哪-->
    <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>

    <!--只用一个/表示任何客户端请求都要经过该前端控制器(如果此处舔*.xxx则意味着只有文件扩展名类型为xxx的请求消息才经过前端控制器)-->
    <url-pattern>/</url-pattern>
    </servlet-mapping>
  4. 创建Controller类和其中的业务方法

  5. 创建视图页面jsp文件

  6. 在Controller类和其中业务方法上添加注解,通过注解使该类中的业务方法成为一个可以接收请求消息的动态资源。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Controller
    @RequestMapping("/user")
    public class UserController {

    @RequestMapping("/quick")//资源路径为/user/quick
    //请求映射注解。(请求消息访问/user/quick动态资源时,服务器映射到save()方法,执行其中代码,并返回一个jsp视图页面名字符串,使客户端直接跳转到该视图。)

    public String save() {
    System.out.println("Controller save running.....");
    return "/success.jsp";
    //"success.jsp"为相对资源路径,到时候会访问的视图动态资源路径为/user/success.jsp,然而这并不存在,所以会404;
    //重要:"/success.jsp"为绝对资源路径,表示直接放在web项目根目录下的资源路径/success.jsp。

    }
    }
  7. 创建spring-mvc.xml文件,主要用来开启mvc的注解扫描和注解驱动。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <?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/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--Controller的组件注解扫描(扫描的包范围最好小一点,这样能确保分工更明确,controller包以外的注解扫描交给核心配置文件来做。)-->
    <context:component-scan base-package="jia.zheng.controller"/>

    <!--配置mvc的注解驱动,使得Controller中的映射方法返回值可以为对象或者集合,且由该驱动默认继承的jackson转换为json格式字符串展示在页面上-->
    <mvc:annotation-driven/>
    </beans>
  8. 部署项目到tomcat上并使用

SpringMVC注解解析

@RequestMapping:用于建立请求 URL 和处理请求方法之间的对应关系

SpringMVC配置视图解析器

在spring-mvc.xml文件中可以配置视图资源解析器,并通过属性注入,来修改视图的前后缀。

SpringMVC的数据响应

SpringMVC的数据响应主要有四种方式

  • 页面跳转
    • 直接返回字符串
    • 返回ModelAndView对象
  • 回写数据
    • 直接返回字符串
    • 返回对象或集合

数据响应为页面跳转_字符串

注意此时作为动态资源的方法的返回值类型必须是String。

  • 直接返回单个页面跳转字符串,Spring会将返回的字符串与视图解析器中配置好的前后缀拼接好,作为转发资源的绝对地址。

  • 也可以返回带有前后缀的完整资源绝对地址,则不用拼接。

    • 转发: forward:/WEB-INF/views/index.jsp
    • 重定向: redirect:/index.jsp

数据响应为页面跳转_ModelAndView对象

注意此时作为动态资源的方法的返回值类型必须是ModelAndView。

数据响应为页面跳转_向request域中存储数据

在进行转发时,往往要向request域中存储数据,使得jsp页面可以使用这些数据。

存储数据的方式主要有两种:

  • 通过SpringMVC框架注入的request对象setAttribute()方法设置

  • 通过ModelAndView的addObject()方法设置

数据响应为回写数据_字符串

数据响应为回写数据时,要在成为动态资源的业务方法上再加一个注解@ResponseBody,这个注解会告知SpringMVC框架,业务方法返回的数据不是跳转数据,而是直接放在在http响应体中返回。 业务方法的返回值类型即为要回写数据的类型。

数据响应为回写数据_json格式字符串

使用Jackson将java对象转换为json字符串并返回的基本步骤:

  1. 在pom.xml文件中导入jackson坐标(注意:每次更改完pom.xml、spring-mvc等配置文件后都要重新创建一次web项目的artifacts导入Tomcat服务器中。)

  2. 创建ObjectMapper对象,并使用其方法将java对象转换成json字符串并返回。

数据响应为回写数据_对象或集合

返回对象或集合的基本步骤:

  1. 在spring-mvc.xml文件中打开mvc的注解驱动

    1
    2
    <!--配置mvc的注解驱动,使得Controller中的映射方法返回值可以为对象或者集合,且由该驱动默认继承的jackson转换为json格式字符串展示在页面上-->
    <mvc:annotation-driven/>
  2. 业务方法返回值类型写成对象类型或者集合类型,mvc会自动帮我们把返回的该对象或集合转换成json字符串放入响应体中。

SpringMVC获得请求数据

获得请求参数

客户端请求参数的格式是: name=value&name=value… …

服务器端要获得请求的参数,有时还需要进行数据的封装,再给到service层和dao层使用。

SpringMVC可以接收如下类型的请求参数:

  • 基本类型参数
  • POJO类型参数
  • 数组类型参数
  • 集合类型参数

获得基本类型参数

使Controller中作为动态资源的业务方法的输入参数与请求参数的name一致,则参数值会自动映射匹配。

获得POJO类型参数

使Controller中的业务方法的POJO参数的属性名与请求参数的name一致,则参数值会自动映射匹配。

获得数组类型参数

使Controller中的业务方法数组名称与请求参数的name一致,则参数值会自动映射匹配。

获得集合类型参数

获得集合参数时,也要将几何参数包装到一个POJO中才可以。

请求数据乱码问题

当post请求时,数据会出现乱码,我们可以在web.xml文件中配置一个过滤器来进行编码的过滤。

参数绑定注解@RequestParam

当请求消息中的请求参数的名称与Controller中的业务方法的输入参数名称不一致时,就需要通过@RequestParam注解来将请求参数与输入参数进行绑定。

自定义类型转换器

SpringMVC默认已经提供了一些常用的类型转换器,例如客户端提供的字符串转换成int型进行参数设置,但是有一些数据类型并没有提供转换器,比如日期类型的数据就需要自定义转换器。

自定义类型转换器的开发步骤:

  1. 定义转换器类,该类实现Converter接口
  2. 在Spring-mvc文件中配置转换器
  3. 在Spring-mvc文件中的<annotation-driven>中引入该转换器

获得Servlet相关API

SpringMVC支持使用原始ServletAPI对象作为Controller中业务方法的输入参数,常用的对象如下:

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession

获得请求头

使用@RequestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)。

使用@CookieValue可以获得指定Cookie的值。

文件上传

  • 文件上传客户端三要素
  • 文件上传原理
  • 单文件上传实现步骤
  • 多文件上传实现步骤

SpringMVC拦截器

拦截器的作用

Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对Controller进行预处理和后处理。 拦截器也是AOP思想的具体实现。

自定义拦截器步骤

  1. 创建拦截器类,该类要实现HandlerInterceptor接口

    其中preHandle()方法最常使用的案例就是:登录验证。客户端页面提交的请求参数中的键值对要符合要求才可以执行目标方法,不符合要求则转发到其他错误提示页面。

  2. 在Spring-mvc.xml文件中配置拦截器

多拦截器操作

拦截器在Spring-mvc.xml配置文件中的配置顺序决定了它们的拦截顺序。

SpringMVC异常处理

异常处理思路

在一个运用了Spring框架的web项目中,dao、service、controller层中出现的异常全都向上抛出,最后由SpringMVC前端控制器交由异常处理器来进行异常处理。

使用SpringMVC内置的简单异常处理器SimpleMappingExceptionResolver

SpringMVC已经定义好了该类型转换器,要使用时在Spring-mvc.xml文件中如下配置即可,可以根据项目情况进行相应异常与视图的映射配置。

使用自定义异常处理器

相比于使用SpringMVC内置的简单异常处理器SimpleMappingExceptionResolver,使用自定义异常处理器则只需要多出一个步骤:创建异常处理器类,该类实现HandlerExceptionResolver。

创建好之后,在Spring-mvc.xml文件中如下配置该异常处理器即可,注意简单异常处理器和自定义异常处理器一般不在同时配置。