第一章 SpringMVC概述

SpringMVC简介

  1. 是基于spring的一个框架, 实际上就是spring的一个模块, 专门是做web开发的。是servlet的一个升级。
  2. SpringMVC就是一个Spring。 SpringMVC能够创建对象, 放入到容器中(SpringMVC容器), springmvc容器中放的是控制器对象。
  3. 使用@Controller创建控制器对象,创建的是一个普通类对象,不是Servlet。SpringMVC赋予了控制器对象接收用户请求,显示处理结果的功能,使其可以当做一个Servlet使用。
  4. web开发底层是servlet, springmvc中有一个对象是Servlet : DispacherServlet(中央调度器)
  5. DispacherServlet: 负责接收用户的所有请求, 用户把请求给了DispacherServlet。

之后DispacherServlet把请求转发给我们的Controller对象, 最后是Controller对象处理请求。

  1. image.png

    第一个注解的SpringMVC程序

    需求:用户在页面发起一个请求, 请求交给springmvc的控制器对象,并显示请求的处理结果(在结果页面显示一个欢迎语句)。
    处理流程:
    some.do—-DispatcherServlet—-MyController

    • 发起some.do
    • tomcat(web.xml—url-pattern知道 *.do的请求给DispatcherServlet)
    • DispatcherServlet(根据springmvc.xml配置知道 some.do—-doSome())
    • DispatcherServlet把some.do转发个MyController.doSome()方法
    • 框架执行doSome()把得到ModelAndView进行处理, 转发到show.jsp

image.png

步骤

  1. 创建maven-web项目
  2. 解决web.xml版本过低问题 ```xml <?xml version=”1.0” encoding=”UTF-8”?>

  1. 3. 添加依赖
  2. 1. SpringMVC依赖——间接把spring的依赖都加入到项目。
  3. <dependency><br /> <groupId>org.springframework</groupId><br /> <artifactId>spring-webmvc</artifactId><br /> <version>5.2.5.RELEASE</version><br /> </dependency>
  4. 2. Servlet依赖
  5. <dependency><br /> <groupId>javax.servlet</groupId><br /> <artifactId>javax.servlet-api</artifactId><br /> <version>3.1.0</version><br /> <scope>provided</scope><br /> </dependency>
  6. 3. 配置Tomcat服务器
  7. 3. 创建springmvc.xml配置文件
  8. 3. 注册中央调度器——DispatcherServlet(⭐)
  9. 1. web.xml中注册
  10. 1. DispatcherServlet叫做中央调度器, 是一个servlet 它的父类是继承HttpServlet
  11. 1. DispatcherServlet也叫做前端控制器(front controller
  12. 1. DispatcherServlet负责接收用户提交的请求, 调用其它的控制器对象, 并把请求的处理结果显示给用户.
  13. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1625672225584-31050735-3686-4870-ae14-8beb4b4f443e.png#clientId=u7ca7c2ec-79b0-4&from=paste&height=505&id=u3e8b53be&name=image.png&originHeight=1010&originWidth=1373&originalType=binary&ratio=1&size=149539&status=done&style=stroke&taskId=uc9c27f44-0325-4a7c-bf3f-b91da57a267&width=686.5)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1625672320366-64b410a1-8fbb-4077-a90e-f2fd3979483a.png#clientId=u7ca7c2ec-79b0-4&from=paste&height=108&id=ub3752e80&margin=%5Bobject%20Object%5D&name=image.png&originHeight=216&originWidth=728&originalType=binary&ratio=1&size=24023&status=done&style=stroke&taskId=ua8b31425-46a4-4ad9-8ce3-1870ae9f5e0&width=364)
  14. 6. 创建发起请求的jsp页面
  15. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1625672608408-34d75f4e-33a7-47ae-8af7-20abfa11817e.png#clientId=u7ca7c2ec-79b0-4&from=paste&height=217&id=u551f0e7a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=433&originWidth=1049&originalType=binary&ratio=1&size=44736&status=done&style=none&taskId=uac1f8152-84cc-4748-956f-ea7082d1be4&width=524.5)
  16. 7. 创建控制器
  17. 1. @Controller:创建处理器对象,将对象放入springmvc容器中.
  18. 修饰的类叫做后端控制器(back Controller
  19. 2. @RequestMapping:请求映射,将请求地址与一个方法绑定在一起。
  20. 1. 属性value
  21. 1. value是一个String,表示请求的url地址(some.do)。
  22. 1. value值唯一,不可重复。
  23. 1. 若有多个请求地址要与此方法绑定,value属性可以写成一个数组。
  24. 1. value的值使用"/"开头,"/"代表——[http://localhost:8080/ch01_hello_springmvc/](http://localhost:8080/ch01_hello_springmvc/)
  25. 2. 使用此注解修饰的方法叫做控制器方法\处理器方法。是可以处理请求的,类似于Servlet中的doGet方法和doPost方法。
  26. 3. ModelAndView
  27. 1. mv.addObeject(key,value); == request.setAttribute(key,value); 框架会将数据放入request域中。
  28. 1. mv.setViewName("/show.jsp"); == request.getRequestDispatcher("/show.jsp").forward(req,resp);
  29. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1625708054338-15af4ab8-35f7-47d6-b5e8-863d408eda52.png#clientId=uf716b174-d134-4&from=paste&height=327&id=u6eadab91&margin=%5Bobject%20Object%5D&name=image.png&originHeight=654&originWidth=1305&originalType=binary&ratio=1&size=85977&status=done&style=none&taskId=u7ee0b6a9-5608-41d6-950f-c08e1e5a30a&width=652.5)
  30. 8. 声明组件扫描器——springmvc.xml
  31. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1625708605544-70d00c94-fa79-4977-a781-9063bf665e11.png#clientId=uf716b174-d134-4&from=paste&height=45&id=u2950c786&name=image.png&originHeight=89&originWidth=836&originalType=binary&ratio=1&size=11864&status=done&style=none&taskId=ue8d27e9d-a452-4937-90d5-9c444b8a24f&width=418)
  32. 9. 定义目标jsp页面——show.jsp显示请求的处理结果。
  33. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1625708648984-9d021d0c-770f-41db-8843-5271db71c355.png#clientId=uf716b174-d134-4&from=paste&height=248&id=u1265d67a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=495&originWidth=1051&originalType=binary&ratio=1&size=48464&status=done&style=none&taskId=uf4d9b709-c5a6-4a6b-b4c7-ff41a3af218&width=525.5)
  34. 10. 注册视图解析器——InternalResourceViewResolver——springmvc.xml
  35. 1. 有些页面是不允许用户直接访问的,会放入WEB-INF目录(安全目录)下
  36. 1. 为了避免请求资源路径与扩展名上的冗余,引入了视图解析器,可以简化请求的前缀与后缀,程序员只需要给出要跳转的页面文件名即可。
  37. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1625709633647-bc4646a1-f4d2-4790-87d6-fd4b808adaf0.png#clientId=uf716b174-d134-4&from=paste&height=153&id=ud2da0a60&margin=%5Bobject%20Object%5D&name=image.png&originHeight=306&originWidth=1290&originalType=binary&ratio=1&size=45998&status=done&style=none&taskId=u189f738d-6c04-48aa-818b-1be94f3586c&width=645)<br />加了前缀和后缀后,Controller中的请求转发就可以改成这样!<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1625709649998-1c9a944c-00ea-4ea4-aab5-3592e2693d52.png#clientId=uf716b174-d134-4&from=paste&height=47&id=uaf48c31c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=94&originWidth=375&originalType=binary&ratio=1&size=6499&status=done&style=none&taskId=u8803d03d-a118-4fb9-90ce-65f2850359d&width=187.5)
  38. <a name="BJsLY"></a>
  39. # 第二章 SpringMVC 注解式开发
  40. <a name="Sx0Fy"></a>
  41. ## @RequestMapping定义请求规则
  42. <a name="zvQXL"></a>
  43. ### 指定模块名称
  44. 1. 通过@RequestMapping 注解可以定义处理器对于请求的映射规则。 该注解可以注解在方法上,也可以注解在类上,但意义是不同的。 value 属性值常以“/”开始。
  45. 1. 一个@Controller 所注解的类中,可以定义多个处理器方法。当然,不同的处理器方法所匹配的 URL是不同的。 这些不同的 URL 被指定在注解于方法之上的@RequestMapping value 属性中。 但若这些请求具有相同的 URL 部分,则这些相同的 URL 可以被抽取到注解在类之上的@RequestMapping value 属性中。此时的这个 URL 表示模块的名称。 URL 的请求是相对于 Web 的根目录。
  46. 1. 要访问处理器的指定方法,必须要在方法指定 URL 之前 加上处理器类前定义的模块名称(类上的@RequestMappingvalue值)
  47. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1625793070771-0f5f8f0a-06d5-4c61-9320-463670ae0366.png#clientId=u4ebc013d-4dbf-4&from=paste&height=334&id=u53449082&margin=%5Bobject%20Object%5D&name=image.png&originHeight=667&originWidth=1079&originalType=binary&ratio=1&size=254086&status=done&style=none&taskId=ue2cf91c0-6a3d-4ffd-8cd2-f2ad35b62cb&width=539.5)<br />访问请求地址——test/some.do
  48. <a name="Itxof"></a>
  49. ### 对提交方式的定义——method
  50. 1. 对于@RequestMapping,其有一个属性 method,用于对被注解方法所处理请求的提交<br />方式进行限制,即只有满足该 method 属性指定的提交方式的请求,才会执行该被注解方法。
  51. 1. method 属性的取值为 RequestMethod 枚举常量。常用的为 RequestMethod.GET 与<br />RequestMethod.POST,分别表示提交方式的匹配规则为 GET POST 提交。
  52. 1. 若不指定method属性,则对于请求的提交方式无要求,getpost都可以。
  53. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1625800396041-7f530891-709d-4f73-a1d1-d071f8aa0bda.png#clientId=u4ebc013d-4dbf-4&from=paste&height=222&id=uc8c031ae&margin=%5Bobject%20Object%5D&name=image.png&originHeight=444&originWidth=1280&originalType=binary&ratio=1&size=75063&status=done&style=none&taskId=ua7b2cb77-296d-4a40-a6cb-7e20fb5792a&width=640)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1625800866261-a35f2c62-5c3c-47a3-a019-ca1b15cd3ee7.png#clientId=u4ebc013d-4dbf-4&from=paste&height=25&id=u00686845&margin=%5Bobject%20Object%5D&name=image.png&originHeight=49&originWidth=886&originalType=binary&ratio=1&size=9060&status=done&style=none&taskId=uf43b42c7-e006-4c77-a2fb-7f3bbe65741&width=443)
  54. <a name="af51d"></a>
  55. #### 回顾get请求与post请求
  56. GET 请求的特点是
  57. 1. 浏览器地址栏中的地址是: action 属性[+?+请求参数]
  58. 请求参数的格式是: name=value&name=value
  59. 2. 不安全
  60. 2. 它有数据长度的限制
  61. 常见的get请求
  62. | 请求方式 | 提交方式 |
  63. | --- | --- |
  64. | 超链接请求(<a>标签) | get请求 |
  65. | 在浏览器地址栏中输入地址后敲回车。 | get请求 |
  66. | form表单请求 | 默认get请求 |
  67. | ajax请求 | 默认get请求 |
  68. POST 请求的特点是
  69. 4. 浏览器地址栏中只有 action 属性值
  70. 4. 相对于 GET 请求要更安全
  71. 4. 理论上没有数据长度的限制
  72. 常见的post请求:
  73. | 请求方式 | 提交方式 |
  74. | --- | --- |
  75. | form表单请求 | 默认get请求,可以指定post请求 |
  76. | ajax请求 | 默认get请求,可以指定post请求 |
  77. 也就是说,只要指定了处理器方法匹配的请求提交方式为 POST,则相当于指定了请求发送的方式: 要么使用表单请求,要么使用 AJAX 请求。其它请求方式被禁用。
  78. <a name="geMQR"></a>
  79. ## 处理器方法的参数
  80. <a name="H66V7"></a>
  81. ### 逐个参数接收
  82. <a name="iGYJj"></a>
  83. #### 请求参数名 与 该请求的处理方法的形参名相同的情况
  84. 只要保证请求参数名与该请求处理方法的参数名相同即可。
  85. 1. 编写index.jsp页面
  86. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1628407150118-ac73720f-6ba0-4978-8ef2-c220d00e8ad5.png#clientId=u26cd3a5f-563b-4&from=paste&height=113&id=u2ad24c5b&name=image.png&originHeight=150&originWidth=550&originalType=binary&ratio=1&size=16577&status=done&style=none&taskId=ubd4986ad-c275-4603-87fc-8f6f31fc78a&width=413)
  87. 2. 编写Controller
  88. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1628407287451-f9f8be8f-7ad2-489c-9a3b-cadb58190abf.png#clientId=u26cd3a5f-563b-4&from=paste&height=179&id=u562bf9fe&name=image.png&originHeight=238&originWidth=630&originalType=binary&ratio=1&size=26097&status=done&style=none&taskId=u7933a1e9-71da-4992-80fb-2c49a827ee2&width=473)
  89. 3. 编写show.jsp
  90. <a name="bI4Lx"></a>
  91. #### 请求参数名 与 该请求的处理方法的形参名不相同的情况——@RequestParam
  92. 若请求的URL所携带的参数名称与处理方法中指定的参数名不相同时,则需要在处理方法参数前,添加一个注解@RequestParam("请求参数名")。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1628410187844-eeecbfe9-30e4-4d24-a614-b7fe9145305c.png#clientId=u26cd3a5f-563b-4&from=paste&height=94&id=ub62b29b2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=187&originWidth=762&originalType=binary&ratio=1&size=80737&status=done&style=none&taskId=ub8c2079d-18bf-431c-a7f4-1d41918db2c&width=381)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1628409907081-a6a61428-ef22-4291-86c5-87ebd84ca398.png#clientId=u26cd3a5f-563b-4&from=paste&height=334&id=ucc10e414&name=image.png&originHeight=667&originWidth=1089&originalType=binary&ratio=1&size=279633&status=done&style=none&taskId=u178802cb-ab3a-423b-9a40-7d204a075c5&width=544.5)
  93. <a name="A3Sda"></a>
  94. #### 解决请求中post请求中文乱码问题-web.xml
  95. get请求不会出现中文乱码,post请求有。<br />**解决方案:**<br />在web.xml中注册字符集过滤器。最好将此过滤器注册在其他过滤器之前。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1628408083168-7b6b6138-40b3-49e7-96bc-ead1698f2a9c.png#clientId=u26cd3a5f-563b-4&from=paste&height=526&id=u1cf6a3b3&name=image.png&originHeight=701&originWidth=1018&originalType=binary&ratio=1&size=73625&status=done&style=none&taskId=u2c9ad07c-9dc3-4a2a-b452-3da0dcd6daa&width=764)
  96. <a name="p6rId"></a>
  97. ### 对象参数接收
  98. 将处理器方法的参数定义为一个对象,只要保证请求参数名与这个对象的属性同名即可。
  99. 1. 定义Student
  100. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1628495408869-a68ce76a-7c69-49fe-b56f-1f876572d787.png#clientId=ub53ccd82-b143-4&from=paste&height=108&id=u0a14e3d3&name=image.png&originHeight=215&originWidth=354&originalType=binary&ratio=1&size=33503&status=done&style=none&taskId=udae0ff64-22cb-4d3b-a521-92a6d0c4a64&width=177)
  101. 2. 编写Controller
  102. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1628495434811-f557c733-9768-475b-9f26-c1e3564e77c3.png#clientId=ub53ccd82-b143-4&from=paste&height=183&id=uba3e6789&name=image.png&originHeight=366&originWidth=633&originalType=binary&ratio=1&size=84695&status=done&style=none&taskId=ubbcb6d58-fe33-4120-8970-a17a8d2f37e&width=316.5)
  103. 3. 编写index,jsp
  104. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1628407150118-ac73720f-6ba0-4978-8ef2-c220d00e8ad5.png#clientId=u26cd3a5f-563b-4&from=paste&height=113&id=teE1b&name=image.png&originHeight=150&originWidth=550&originalType=binary&ratio=1&size=16577&status=done&style=none&taskId=ubd4986ad-c275-4603-87fc-8f6f31fc78a&width=413)
  105. <a name="WWS9H"></a>
  106. ## 处理器方法的返回值
  107. 1. ModelAndView(数据+视图)
  108. 1. String(视图)
  109. 1. void(了解)
  110. 1. Object对象(Ajax请求)
  111. <a name="jS8Z1"></a>
  112. ### 返回ModelAndView
  113. Model——数据<br />View——视图<br />**适用于:**
  114. 1. 需要跳转到其他资源(请求转发)。
  115. 1. 跳转的资源间传递数据。
  116. **不适用于:**
  117. 1. 只进行跳转而不传递数据
  118. 1. 只传递数据并不向任何资源跳转(如Ajax异步响应)
  119. **常用方法:**
  120. 1. 向前端传递数据:mv.addObject(); == request.setAttribute();
  121. 1. 请求转发:mv.setViewName("show");——默认是请求转发。
  122. 1. 请求重定向:mv.setViewName(**"redirect:/other.jsp"**);
  123. <a name="vpue5"></a>
  124. ### 返回String
  125. **适用于:**
  126. 1. 只跳转到其他资源(请求转发)。
  127. 1. 若要在跳转的同时传递数据,需要通过request作用域传递数据。
  128. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2858485/1630291392690-ea1d0fa9-fe1e-4926-8d1e-853cc55188ec.png#clientId=u9634d4a8-5485-4&from=paste&height=253&id=u11468b7e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=505&originWidth=1519&originalType=binary&ratio=1&size=120224&status=done&style=none&taskId=u26f53db4-8883-4a1a-9c15-349ec1c4620&width=759.5)
  129. <a name="NnCiZ"></a>
  130. ### 返回void(了解)
  131. 1. 适用于处理ajax请求。
  132. 1. ajax请求服务器端返回的就是数据,与视图无关。
  133. <a name="CfDIK"></a>
  134. ### 返回对象Object⭐
  135. 例如String,IntegerMapListStudent等都是对象,对象有属性,属性就是数据。所以返回Object表示数据和视图无关。可以使用对象表示的数据,响应ajax请求。<br />**步骤:**
  136. 1. 加入处理json的工具库依赖,SpringMVC默认使用的是Jackson
  137. Object 转换为 JSON,是由 Jackson 工具完成的。
  138. ```xml
  139. <!--jackson依赖-->
  140. <dependency>
  141. <groupId>com.fasterxml.jackson.core</groupId>
  142. <artifactId>jackson-core</artifactId>
  143. <version>2.9.0</version>
  144. </dependency>
  145. <dependency>
  146. <groupId>com.fasterxml.jackson.core</groupId>
  147. <artifactId>jackson-databind</artifactId>
  148. <version>2.9.0</version>
  149. </dependency>
  1. 在springmvc配置文件之间加入<mvc:annotation-driven/> 注解驱动(mvc结尾的那个)。
    1. 作用:将java对象转换为json,text等格式的数据。
  2. 在处理器方法的上面添加@ResponseBody注解。和其他注解没有先后顺序的要求。
    1. 作用:通过HttpServletResponse输出数据给浏览器,响应ajax请求的。

HttpMessageConverter接口实现类(7个)
重要的两个:

  1. StringHttpMessageConverter:负责读取字符串格式的数据和写出字符串格式的数据。
  2. MappingJackson2MessageConverter:负责读取和写入json格式的数据。利用J ackson的ObjectMapper读写json数据,操作Object类型数据,可读取application/json,响应媒体类型为application/json。

面试题:SpringMVC的处理器方法返回值是json,怎么来实现?

  1. 添加Jackson依赖
  2. 加入注解驱动
  3. 在处理器方法上添加@Response注解。

    返回自定义类型对象

    返回自定义类型对象时,不能以对象的形式直接返回给客户端浏览器,而是将对象转换
    为 JSON 格式的数据发送给浏览器的 .

  4. 定义数据类

image.png

  1. 编写处理器方法

image.png

  1. 修改index页面

image.png

返回List集合

  1. 编写处理器方法

image.png

  1. 修改index.jsp页面

image.png

返回String对象

  1. 此时String表示的是数据,不是视图。

如何区分?
根据处理器方法是是否有@ResponseBody注解来区分。有—数据,没有—视图。

  1. 若返回的字符串中带有中文字符,则会出现乱码。

因为默认使用的是“text/plain;charset=ISO-8859-1”作为contentType,导致中文有乱码。
需要使用@RequestMapping中的produces属性指定字符集为——“text/plain;charset=utf-8”

  1. 步骤
    1. 修改处理器方法

image.png

  1. 编写index.jsp页面

image.png

解读

配置详解

  1. *.do之类的

image.png这种情况没啥特殊的。

  1. “/“

image.png
“/“ 会替代Tomcat中的default导致所有的静态资源都给DispatcherServlet处理,默认情况下DispatcherServlet没有处理静态资源的能力,所以访问静态资源会报错!

静态资源的访问

的值并不是说写为/后,静态资源就无法访问了。经过一些配置后,该问
题也是可以解决的。

使用

只需要在 springmvc.xml 中添加标签即可。

使用(掌握)

js,html等都是静态资源,也需配置,为了方便可以统一放到static目录下。
image.png
location: 表示静态资源所在目录。 当然, 目录不要使用/WEB-INF/及其子目录。
mapping:表 示 对 该 资 源 的 请 求 ( 以 /images/ 开 始 的 请 求 , 如 /image/beauty.jpg ,
/images/car.png 等)。注意,后面是两个星号**。

解决JSP页面中的路径问题

用”/“还是不用?
在jsp , html中使用的地址, 都是在前端页面中的地址,都是相对地址。
后端用,前端不用!

第三章 SSM整合开发

SSM 整合的实现方式可分为两种:基于 XML 配置方式,基于注解方式。

步骤

  1. 创建相关数据库
  2. 新建maven-web项目
  3. 添加maven依赖
  4. 定义程序的包结构
  5. 编写配置文件
    1. jdbc属性配置文件—jdbc.properties
    2. Spring配置文件—applicationContext.xml——声明service,dao,工具类等对象
    3. SpringMVC配置文件—springmvc.xml——声明controller和其它web相关的对象
    4. MyBatis主配置文件—mybatis.xml
  6. 编写web.xml
    1. 注册字符集过滤器——用于解决post请求参数中携带中文时产生的乱码问题。
    2. 注册ContextLoaderListener监听器——用于创建Spring容器以及将创建好的Spring容器对象放入到ServletContext作用域中。
    3. 配置中央调度器——创建springmvc容器对象,读取springmvc的配置文件,把这个配置文件中的对象都创建好。
  7. 编写实体类
  8. 编写Dao接口和sql映射文件
  9. 编写Service接口和实现类
  10. 编写Controller类
  11. 编写jsp页面

    第四章 SpringMVC核心技术

    请求重定向和转发

    forward:表示转发,实现 request.getRequestDispatcher(“xx.jsp”).forward()
    redirect:表示重定向,实现 response.sendRedirect(“xxx.jsp”)
    mv.setViewName(“show”);——默认是请求转发。
    以下两种方式 就当项目中没有视图解析器。
    mv.setViewName(“forward:/WEB-INF/view/show.jsp);——用于需要跳转到与视图解析器不同的视图中。
    mv.setViewName(“redirect:/other.jsp”);

    请求转发

  12. 浏览器的地址栏没有变化,它们只进行了一次请求。

  13. 它们共享Request域中的数据。
  14. 可以请求转发到WEB-INF目录下(直接访问是访问不了的)。
  15. 不可以访问工程以外的资源。

    请求重定向

  16. 浏览器的地址栏发生了变化,它们进行了两次请求。

  17. 它们不共享Request域中的数据。
  18. 不可以访问WEB-INF下的资源
  19. 可以访问工程以外的资源。

    异常处理

    SpringMVC 框架处理异常的常用方式:使用@ExceptionHandler 注解处理异常。

    步骤

  20. 新建maven web项目

  21. 加入依赖
  22. 新建一个自定义异常类 MyUserException , 再定义它的子类NameException ,AgeException
  23. 在controller抛出NameException , AgeException
  24. 创建一个普通类,作用全局异常处理类
    1. 在类的上面加入@ControllerAdvice
    2. 在类中定义方法,方法的上面加入@ExceptionHandler
  25. 创建显示异常的jsp页面
  26. 创建springmvc的配置文件

    1. 组件扫描器 ,扫描@Controller注解
    2. 组件扫描器,扫描@ControllerAdvice所在的包名
    3. 声明注解驱动

      两个注解

      @ControllerAdvice
  27. 控制器增强,给控制器类增加功能——异常处理功能

  28. 使用了@ControllerAdvice修饰的类中可以使用@ExceptionHandler
  29. 当@RequestMapping注解修饰的方法抛出异常时,会执行@ControllerAdvice修饰的类中的异常处理方法。
  30. 位置——类的上面
  31. 需要在springmvc配置文件中声明组件扫描器,指定@ControllerAdvice所在的包名。

@ExceptionHandler

  1. 使用注解@ExceptionHandler 可以将一个方法指定为异常处理方法。
  2. 该注解只有一个可选属性 value,为一个 Class<?>数组,用于指定该注解的方法所要处理的异常类,即所要匹配的异常。

    拦截器

  3. SpringMVC 中的 Interceptor 拦截器是非常重要和相当有用的,它的主要作用是拦截指定的用户请求,并进行相应的 预处理 与 后处理。

  4. 拦截器是全局的,可以对多个Controller做拦截,一个项目中可以有0个或多个拦截器,它们在一起拦截用户的请求。
  5. 拦截器常用于:用户登录处理,权限检查,记录日志。
  6. 一个拦截器的执行

image.png

实现步骤

  1. 新建maven web项目
  2. 加入依赖
  3. 创建Controller类
  4. 创建一个普通类,作为拦截器使用
    1. 实现HandlerInterceptor接口
    2. 实现接口中的三个方法
  5. 创建show.jsp
  6. 创建springmvc的配置文件

    1. 组件扫描器 ,扫描@Controller注解
    2. 注册拦截器,并指定拦截的请求URI地址

      HandlerInterceptor接口的三个方法

      ⭐preHandler—预处理方法

      boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):
  7. 该方法在处理器方法执行之前执行,返回值为boolean,若返回true则紧接着会执行处理器方法。

  8. 此方法中可以获取请求的信息,验证请求是否符合要求(类似于检票口),可以验证用户是否已登录,是否有权限访问某个链接地址(url)。
  9. 返回true时:请求是通过了拦截器的验证,可以执行处理器方法。

          拦截器的MyInterceptor的preHandle()<br />             =====执行MyController中的doSome方法=====<br />             拦截器的MyInterceptor的postHandle()<br />             拦截器的MyInterceptor的afterCompletion()
    
  10. 返回false:请求没有通过拦截器的验证,请求到达拦截器就截止了。 请求没有被处理

    拦截器的MyInterceptor的preHandle()

    postHandler—后处理方法

    void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView):

  11. 该方法在处理器方法执行之后执行的。

  12. 能够获取到处理器方法的返回值ModelAndView,可以修改ModelAndView中的数据和视图,可以影响到最后的执行结果。
  13. 主要是对原来的执行结果做二次修正。

    afterCompletion—最后执行的方法

    void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

  14. 在请求处理完成后执行的。(对视图执行了forward代表执行完成。)

  15. 一般做资源回收工作的, 程序请求过程中创建了一些对象,在这里可以删除,把占用的内存回收。

    注册拦截器—springmvc.xml

    :用于指定当前所注册的拦截器可以拦截的请求路径。
    /表示拦截所有请求。
    /user/**:表示user下的所有请求 ——http://localhost:8080/myweb/user/listUser.do
    image.png

    多个拦截器的执行

  16. 多个拦截器中方法与处理器方法的执行顺序如下图:

image.png

  1. 当拦截器1—preHandle=true,拦截器2——preHandle=true

image.png

  1. 当拦截器1—preHandle=true,拦截器2——preHandle=false

image.png

  1. 当拦截器1—preHandle=false,拦截器2——preHandle=随意

image.png

拦截器与过滤器的区别

  1. 过滤器是servlet中的对象, 拦截器是框架中的对象
  2. 过滤器实现Filter接口的对象, 拦截器是实现HandlerInterceptor
  3. 过滤器是用来设置request,response的参数,属性的,侧重对数据过滤的。

    拦截器是用来验证请求的,能截断请求。

  4. 过滤器是在拦截器之前先执行的。

  5. 过滤器是tomcat服务器创建的对象拦截器是springmvc容器中创建的对象
  6. 过滤器是一个执行时间点。拦截器有三个执行时间点
  7. 过滤器可以处理jsp,js,html等等拦截器是侧重拦截对Controller的对象。

    如果你的请求不能DispatcherServlet接收, 这个请求不会执行拦截器内容

  8. 拦截器拦截普通类方法执行,过滤器过滤servlet请求响应

    权限拦截器举例

    步骤

  9. 新建maven-web项目

  10. 修改web.xml注册中央调度器
  11. 新建index.jsp发起请求
  12. 创建MyController处理请求
  13. 创建结果show.jsp
  14. 创建一个login.jsp,模拟登录(把用户的信息放入到session)
  15. 创建一个jsp, logout.jsp,模拟退出系统(从session中删除数据)
  16. 创建拦截器,从session中获取用户的登录数据,验证能否访问系统
  17. 创建一个验证的jsp,如果验证视图,给出提示
  18. 创建springmvc配置文件
    1. 声明组件扫描器
    2. 声明拦截器