从0到1认识SpringMVC

207 阅读9分钟
  • spirngmvc概述

    • SpringMVC是一种基于java实现的MVC设计模型的请求驱动类型的轻量级Web框架,属于SpringFrameWork的后续产品,已经融合在Spring Web Flow中
    • SpringMVC已经成为目前最主流的MVC框架之一,并且随之Spring3.0的发布,全面超越struts2,成为最优秀的MVC框架。还支持restful风格
  • springmvc开发步骤

    • 导入SpringMVC相关坐标
    • 配置SpirngMVC核心控制器DispatcherServlet
    • 创建controller类和视图页面
    • 使用注解配置Controller类中的业务方法的映射地址
    • 配置SpirngMVC核心文件Spring-MVC.xml
    • 客户端发请求测试

SpringMVC组件解析

SpringMVC相关组件

  • 前端控制器:DispatcherServlet
  • 处理器映射器:HandlerMapping
  • 处理器适配器:HandlerAdapter
  • 处理器(控制器):Handler(Controller)
  • 视图解析器:ViewResolver
  • 视图:View

SpirngMVC执行流程

  • 用户发送请求至前端控制器DispatcherServlet
  • DispatcherServlet收到请求调用HandlerMapping处理器映射器
  • 处理器映射器找到具体的处理器(xml配置或者注解进行查找),生成处理器对象及处理器拦截器(有就生成)并规定好顺序生成一个执行链返回给DispacherServlet
  • DispatcherServlet再调用HandlerAdapter处理器适配器
  • HandlerAdapter经过顺序调用具体的适配器(主要是Controller)
  • Controller执行完返回ModelAndView返回给前端控制器
  • 前端控制器将ModelAndView传给ViewReslover视图解析器
  • 视图解析器返回最后的具体的View
  • 前端控制器根据view进行渲染视图(并将model填充至view中),DispatcherServlet响应用户

SpringMVC注解解析

  • @RequestMapping(value,method,params):用于建立请求url和处理请求方法之间的对应关系,可以放在类上和方法上,value:用于指定请求的url,method:用于指定请求的方式,params:用于指定限制请求参数的条件

SpringMVC的默认视图解析

  • 视图解析器:
    • SpringMVC有默认组件配置,默认组件都是DispatcherServlet.properties配置文件中配置的,该配置文件地址org/springframework/web/servlet/DispatcherServlet.properties,该文件配置了默认的视图解析器,(org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver),InternalResourceViewResolver的父类UrlBasedViewResolver中有四个默认属性
  • REDIRECT_URL_PREFIX = ‘redirect:’—(重定向前缀)
  • FORWARD_URL_PREFIX = ‘forward:’—(请求转发前缀)(默认值)
  • prefix = ”—(视图名称前缀)
  • suffix = ”—(视图名称后缀)

jsp视图解析器

<?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">

    <context:component-scan base-package="com.wsh.controller"></context:component-scan>
    <!--配置JSP视图解析器-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/templates/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--开启注解驱动,否则控制器中带有@RequestMapping的方法失效-->
    <mvc:annotation-driven/>
    <!--指定请求返回对应页面-->
    <mvc:view-controller path="/index" view-name="index"></mvc:view-controller>
</beans>

Thymeleaf视图解析器

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
引入thymeleaf模板
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>首页</h1>

</body>
</html>

<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
    <property name="order" value="1"/>
    <property name="characterEncoding" value="UTF-8"/>
    <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 name="suffix" value=".html"/>
                    <property name="templateMode" value="HTML5"/>
                    <property name="characterEncoding" value="UTF-8" />
                </bean>
            </property>
        </bean>
    </property>
</bean>

SpringMVC的数据响应

SpringMVC的数据响应方式

  • 1.页面跳转
    • 直接返回字符串
    • 通过modelandview对象返回
  • 2.回写数据
    • 直接返回字符串
    • 返回对象或集合
      • 1—–通过SpringMVC帮助我们对对象或集合进行json字符串的转换并回写,找到 DispatcherServlet.properties中的处理器适配器(RequestMappingHandlerAdapter),在xml中通过setter方法设置这个类中的messageConverters(消息转换器),需要的时HttpMessageConverter这个类型的转换器对象(MappingJackson2HttpMessageConverter)
      • 2—–以上配置较麻烦,在springMVC的各个组件中,处理器映射器,处理器适配器,视图解析器称为三大组件。使用mvc:annotation-driver自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter同时默认底层就会集成jackson进行对象或集合的json格式字符串的转换

SpringMVC获取请求数据

获得请求参数:客户端请求参数的格式:name=value&name=Value

参数类型:

  • 基本类型参数
    • Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。并且能自动做类型转换;自动的类型转换是指从String向其他类型的转换
  • pojo实体类型参数
    • Controller中的业务方法的POJO参数的属性名(准确说是找set方法,比如setName,找的就是name)与请求参数的name一致,参数值会自动映射匹配
  • 数组类型参数
    • Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配
  • 集合类型参数
    • 获得集合参数时,要将集合参数包装到一个POJO中才可以,vo-集合参数封装的实体类
    • 当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequestBody可以直接接收集合数据而无需使用POJO进行包装

静态资源访问的开启

当有静态资源需要加载时,比如jquery文件,通过谷歌开发者工具抓包发现,没有加载到jquery文件,原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是/,代表对所有的资源都进行过滤操作,我们可以通过以下两种方式指定放行静态资源:

  • 在spring-mvc.xml配置文件中指定放行的资源:<mvc:resources mapping=”/js/**”location=”/js/”/> mapping为请求的资源路径,location为映射的资源路径
  • 使用mvc:标签
    • 当mvc资源没找到时,会交由原始的容器,其内部会帮忙去找静态资源

请求数据乱码问题

当post请求时,数据会出现乱码,我们可以设置一个过滤器来进行编码的过滤

参数绑定注解@RequestParam

当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定

我们在获取参数的时候上面讲解都是传递参数名要和方法内的形参名相同才可以获取到,但是前后端分离的 时候有时候会出现人员核对出错导致传递参数名和方法内规定的参数名不同,那样就会导致参数获取为null,所以我们可以使用注解@RequestParam来进行注解绑定,只要方法内的参数通过这个注解限定后就会自动和前端传递来的参数进行匹配上

注解参数:

  • value:请求参数名称
  • required:指定的请求参数是否必须存在,默认是true,提交时如果没有此参数则报错,可以可无的参数可以改为false
  • defaultValue:当没有指定请求参数时,则使用指定的默认值赋值

获得restful风格的参数

Restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。

Restful风格的请求是使用“url+请求方式”表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下

  • GET:用于获取资源
  • POST:用于新建资源
  • PUT:用于更新资源
  • DELETE:用于删除资源

自定义类型转换器

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

自定义类型转换器的开发步骤
  • 定义转换器类实现Converter接口
    • Converter中第一个泛型代表转换前的类型,第二个代表转换后的类型
  • 在配置文件中声明转换器
  • 在中引用转换器

获得Servlet相关API

SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入,常用的对象如下

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession

获得请求头信息

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

  • value:请求头的名称
  • required:是否必须携带此请求头

@CookieValue

使用@CookieValue可以获得指定Cookie的值
@CookieValue注解的属性如下

  • value:指定cookie的名称
  • required:是否必须携带此cookie

文件上传

  • 表单项type=”file”
  • 表单提交的方式时post请求
  • 表单的enctype属性时多部分表单形式,及enctype=”multipart/form-data”
文件上传原理
  • 当form表单修改为多部份表单时,request.getParameter()将失效
  • enctype=”application/x-www-form-urlencoded”时,form表单的正文内容格式是: key=value&key=value
  • 当enctype=”multipart/form-data”请求正文内容就变成多部份形式

单文件上传步骤

  • fileupload和io坐标
  • 配置文件上传解析器
  • 编写文件上传代码
MultipartFile对象中的常用方法
  • byte[] getBytes():获取文件数据
  • String getContentType[]:获取文件MIME类型,如image/jpeg等
  • InputStream getInputStream():获取文件流
  • String getName():获取表单中文件组件的名字
  • String getOriginalFilename():获取上传文件的原名
  • Long getSize():获取文件的字节大小,单位为byte
  • boolean isEmpty():是否有上传文件
  • void transferTo(File dest):将上传文件保存到一个目录文件中

多文件上传

步骤和单文件一样

当表单中文件的name不相同时,后端可分别接收,当表单中文件的name相同时,可以用MultipartFile[]数组来接收,并遍历保存在磁盘中。

SpringMVC拦截器

拦截器(interceptor)的作用

SpringMVC的拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理.

将拦截器按一定的顺序连接成一条链,这条链称为拦截器链(preHandle按顺序执行,其他两个按倒叙执行)。

拦截器和过滤器的区别

拦截器快速入门

  • 创建拦截器类实现HandlerInterceptor接口
  • 配置拦截器
  • 测试效果

拦截器方法说明

SpringMVC异常处理

异常处理思路

系统中异常包括两类:编译异常(受检异常)和运行异常(非受检异常),前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发,测试等手段减少运行时异常的发生

系统的dao,service,controller,出现都通过throws Exception向上抛出,最后由springMVC前端控制器交由异常处理器进行异常处理,如下图:

异常处理的两种方式

  • 使用SpringMVC提供的简单异常处理器SimpleMappingExceptionResolver
  • 实现Spring的异常处理接口HandlerExceptionResolver自定义自己的异常处理器

自定义异常处理步骤

  • 创建异常处理器类实现HandlerExceptionResolver
  • 配置异常处理器
  • 编写异常页面

SpringMVC集成web

<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 天,点击查看活动详情