一、SpringMVC快速入门、组件解析

1. Spring与Web环境集成

1.1 ApplicationContext应用上下文获取方式

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

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

1.2 Spring提供获取应用上下文的工具

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

所以我们需要做的只有两件事:

  1. 在web.xml中配置ContextLoaderListener监听器(导入spring-web坐标)
  2. 使用WebApplicationContextUtils获得应用上下文对象ApplicationContext

1.3 导入Spring集成web的坐标

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

1.4 配置ContextLoaderListener监听器

<!--全局参数-->
<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--Spring的监听器-->
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>

1.5 通过工具获得应用上下文对象

ApplicationContext applicationContext =    WebApplicationContextUtils.getWebApplicationContext(servletContext);Object obj = applicationContext.getBean("id");

知识要点

Spring集成web环境步骤

​ ①配置ContextLoaderListener监听器

​ ②使用WebApplicationContextUtils获得应用上下文

2. SpringMVC的简介

2.1 SpringMVC概述

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 中。

SpringMVC 已经成为目前最主流的MVC框架之一,并且随着Spring3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。

2.3 SpringMVC快速入门

需求:客户端发起请求,服务器端接收请求,执行逻辑并进行视图跳转。

开发步骤

①导入SpringMVC相关坐标

②配置SpringMVC核心控制器DispathcerServlet

③创建Controller类和视图页面

④使用注解配置Controller类中业务方法的映射地址

⑤配置SpringMVC核心文件 spring-mvc.xml

⑥客户端发起请求测试

代码实现

①导入Spring和SpringMVC的坐标、导入Servlet和Jsp的坐标

 <!--Spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.5.RELEASE</version></dependency><!--SpringMVC坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.0.5.RELEASE</version></dependency>
<!--Servlet坐标-->
<dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version>
</dependency>
<!--Jsp坐标-->
<dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.0</version>
</dependency>

②在web.xml配置SpringMVC的核心控制器

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

③创建Controller和业务方法

public class QuickController {public String quickMethod(){System.out.println("quickMethod running.....");return "index";}
}

③创建视图页面index.jsp

<html>
<body><h2>Hello SpringMVC!</h2>
</body>
</html>

④配置注解

@Controller
public class QuickController {@RequestMapping("/quick")public String quickMethod(){System.out.println("quickMethod running.....");return "index";}
}

⑤创建spring-mvc.xml

<beans xmlns="http://www.springframework.org/schema/beans"  xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc   http://www.springframework.org/schema/mvc/spring-mvc.xsd  http://www.springframework.org/schema/context   http://www.springframework.org/schema/context/spring-context.xsd"><!--配置注解扫描--><context:component-scan base-package="com.itheima"/>
</beans>

⑥访问测试地址

http://localhost:8080/itheima_springmvc1/quick

控制台打印

页面显示

2.3 SpringMVC流程图示

2.4 知识要点

SpringMVC的开发步骤

①导入SpringMVC相关坐标

②配置SpringMVC核心控制器DispathcerServlet

③创建Controller类和视图页面

④使用注解配置Controller类中业务方法的映射地址

⑤配置SpringMVC核心文件 spring-mvc.xml

⑥客户端发起请求测试

3. SpringMVC的组件解析

3.1 SpringMVC的执行流程

①用户发送请求至前端控制器DispatcherServlet。

②DispatcherServlet收到请求调用HandlerMapping处理器映射器。

③处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

④DispatcherServlet调用HandlerAdapter处理器适配器。

⑤HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

⑥Controller执行完成返回ModelAndView。

⑦HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

⑧DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

⑨ViewReslover解析后返回具体View。

⑩DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet响应用户。

3.2 SpringMVC组件解析

  1. 前端控制器:DispatcherServlet

​ 用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由

它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。

  1. 处理器映射器:HandlerMapping

​ HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的

映射方式,例如:配置文件方式,实现接口方式,注解方式等。

  1. 处理器适配器:HandlerAdapter

​ 通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理

器进行执行。

  1. 处理器:Handler

​ 它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由

Handler 对具体的用户请求进行处理。

  1. 视图解析器:View Resolver

​ View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

  1. 视图:View

​ SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面

3.3 SpringMVC注解解析

@RequestMapping

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

位置:

​ 类上,请求URL 的第一级访问目录。此处不写的话,就相当于应用的根目录

​ 方法上,请求 URL 的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径

属性:

​ value:用于指定请求的URL。它和path属性的作用是一样的

​ method:用于指定请求的方式

​ params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样

例如:

​ params = {“accountName”},表示请求参数必须有accountName

​ params = {“moeny!100”},表示请求参数中money不能是100

1.mvc命名空间引入

命名空间:xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"
约束地址:http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd

组件扫描

SpringMVC基于Spring容器,所以在进行SpringMVC操作时,需要将Controller存储到Spring容器中,如果使用@Controller注解标注的话,就需要使用<context:component-scan base-package=“com.itheima.controller"/>进行组件扫描。

3.4 SpringMVC的XML配置解析

SpringMVC有默认组件配置,默认组件都是DispatcherServlet.properties配置文件中配置的,该配置文件地址org/springframework/web/servlet/DispatcherServlet.properties,该文件中配置了默认的视图解析器,如下:

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

翻看该解析器源码,可以看到该解析器的默认设置,如下:

REDIRECT_URL_PREFIX = "redirect:"  --重定向前缀
FORWARD_URL_PREFIX = "forward:"    --转发前缀(默认值)
prefix = "";     --视图名称前缀
suffix = "";     --视图名称后缀
  1. 视图解析器

我们可以通过属性注入的方式修改视图的的前后缀

<!--配置内部资源视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/"></property><property name="suffix" value=".jsp"></property>
</bean>

3.5 知识要点

SpringMVC的相关组件

前端控制器:DispatcherServlet

处理器映射器:HandlerMapping

处理器适配器:HandlerAdapter

处理器:Handler

视图解析器:View Resolver

视图:View

SpringMVC的注解和配置

请求映射注解:@RequestMapping

视图解析器配置:

REDIRECT_URL_PREFIX = “redirect:”

FORWARD_URL_PREFIX = “forward:”

prefix = “”;

suffix = “”;

二、SpringMVC的请求和响应

1. SpringMVC的数据响应

1.1 SpringMVC的数据响应-数据响应方式(理解)

  1. 页面跳转

直接返回字符串

通过ModelAndView对象返回

2) 回写数据

直接返回字符串

返回对象或集合

1.2 SpringMVC的数据响应-页面跳转-返回字符串形式(应用)

1.3 SpringMVC的数据响应-页面跳转-返回ModelAndView形式1(应用)

在Controller中方法返回ModelAndView对象,并且设置视图名称

@RequestMapping(value="/quick2")public ModelAndView save2(){/*Model:模型 作用封装数据View:视图 作用展示数据*/ModelAndView modelAndView = new ModelAndView();//设置模型数据modelAndView.addObject("username","itcast");//设置视图名称modelAndView.setViewName("success");return modelAndView;}

1.4 SpringMVC的数据响应-页面跳转-返回ModelAndView形式2(应用)

n在Controller中方法形参上直接声明ModelAndView,无需在方法中自己创建,在方法中直接使用该对象设置视图,同样可以跳转页面

 @RequestMapping(value="/quick3")public ModelAndView save3(ModelAndView modelAndView){modelAndView.addObject("username","itheima");modelAndView.setViewName("success");return modelAndView;}
@RequestMapping(value="/quick4")public String save4(Model model){model.addAttribute("username","博学谷");return "success";}

1.5 SpringMVC的数据响应-页面跳转-返回ModelAndView3(应用)

在Controller方法的形参上可以直接使用原生的HttpServeltRequest对象,只需声明即可

@RequestMapping(value="/quick5")public String save5(HttpServletRequest request){request.setAttribute("username","酷丁鱼");return "success";}

1.6 SpringMVC的数据响应-回写数据-直接回写字符串(应用)

通过SpringMVC框架注入的response对象,使用response.getWriter().print(“hello world”) 回写数据,此时不需要视图跳转,业务方法返回值为void

将需要回写的字符串直接返回,但此时需要通过@ResponseBody注解告知SpringMVC框架,方法返回的字符串不是跳转是直接在http响应体中返回

@RequestMapping(value="/quick7")@ResponseBody  //告知SpringMVC框架 不进行视图跳转 直接进行数据响应public String save7() throws IOException {return "hello itheima";}@RequestMapping(value="/quick6")public void save6(HttpServletResponse response) throws IOException {response.getWriter().print("hello itcast");}

1.7 SpringMVC的数据响应-回写数据-直接回写json格式字符串(应用)

@RequestMapping(value="/quick8")@ResponseBodypublic String save8() throws IOException {return "{\"username\":\"zhangsan\",\"age\":18}";}

手动拼接json格式字符串的方式很麻烦,开发中往往要将复杂的java对象转换成json格式的字符串,我们可以使用web阶段学习过的json转换工具jackson进行转换,通过jackson转换json格式字符串,回写字符串

@RequestMapping(value="/quick9")@ResponseBodypublic String save9() throws IOException {User user = new User();user.setUsername("lisi");user.setAge(30);//使用json的转换工具将对象转换成json格式字符串在返回ObjectMapper objectMapper = new ObjectMapper();String json = objectMapper.writeValueAsString(user);return json;}

1.8 SpringMVC的数据响应-回写数据-返回对象或集合(应用)

通过SpringMVC帮助我们对对象或集合进行json字符串的转换并回写,为处理器适配器配置消息转换参数,指定使用jackson进行对象或集合的转换,因此需要在spring-mvc.xml中进行如下配置:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="messageConverters"><list><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/></list></property></bean>
@RequestMapping(value="/quick10")@ResponseBody//期望SpringMVC自动将User转换成json格式的字符串public User save10() throws IOException {User user = new User();user.setUsername("lisi2");user.setAge(32);return user;}

1.9 SpringMVC的数据响应-回写数据-返回对象或集合2(应用)

在方法上添加@ResponseBody就可以返回json格式的字符串,但是这样配置比较麻烦,配置的代码比较多,因此,我们可以使用mvc的注解驱动代替上述配置

<mvc:annotation-driven/>

在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。

使用<mvc:annotation-driven />自动加载 RequestMappingHandlerMapping(处理映射器)和

RequestMappingHandlerAdapter( 处 理 适 配 器 ),可用在Spring-xml.xml配置文件中使用

<mvc:annotation-driven />替代注解处理器和适配器的配置。

同时使用<mvc:annotation-driven />

默认底层就会集成jackson进行对象或集合的json格式字符串的转换

1.10 SpringMVC的数据响应-知识要点小结(理解,记忆)

1) 页面跳转

直接返回字符串

通过ModelAndView对象返回

2) 回写数据

直接返回字符串

HttpServletResponse 对象直接写回数据,HttpServletRequest对象带回数据,Model对象带回数据或者@ResponseBody将字符串数据写回

返回对象或集合

@ResponseBody+<mvc:annotation-driven/>

2. SpringMVC的请求

2.1 SpringMVC的请求-获得请求参数-请求参数类型(理解)

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

服务器端要获得请求的参数,有时还需要进行数据的封装,SpringMVC可以接收如下类型的参数

基本类型参数

POJO类型参数

数组类型参数

集合类型参数

2.2 SpringMVC的请求-获得请求参数-获得基本类型参数(应用)

Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。并且能自动做类型转换;

自动的类型转换是指从String向其他类型的转换

http://localhost:8080/itheima_springmvc1/quick9?username=zhangsan&age=12

@RequestMapping(value="/quick11")@ResponseBodypublic void save11(String username,int age) throws IOException {System.out.println(username);System.out.println(age);}

2.3 SpringMVC的请求-获得请求参数-获得POJO类型参数(应用)

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

package com.itheima.domain;public class User {private String username;private int age;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", age=" + age +'}';}
}
@RequestMapping(value="/quick12")@ResponseBodypublic void save12(User user) throws IOException {System.out.println(user);}

2.4 SpringMVC的请求-获得请求参数-获得数组类型参数(应用)

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

@RequestMapping(value="/quick13")@ResponseBodypublic void save13(String[] strs) throws IOException {System.out.println(Arrays.asList(strs));}

2.5 SpringMVC的请求-获得请求参数-获得集合类型参数1(应用)

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

<form action="${pageContext.request.contextPath}/user/quick14" method="post"><%--表明是第一个User对象的username age--%><input type="text" name="userList[0].username"><br/><input type="text" name="userList[0].age"><br/><input type="text" name="userList[1].username"><br/><input type="text" name="userList[1].age"><br/><input type="submit" value="提交"></form>
package com.itheima.domain;import java.util.List;public class VO {private List<User> userList;public List<User> getUserList() {return userList;}public void setUserList(List<User> userList) {this.userList = userList;}@Overridepublic String toString() {return "VO{" +"userList=" + userList +'}';}
}
@RequestMapping(value="/quick14")@ResponseBodypublic void save14(VO vo) throws IOException {System.out.println(vo);}

2.6 SpringMVC的请求-获得请求参数-获得集合类型参数2(应用)

当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequestBody可以直接接收集合数据而无需使用POJO进行包装

<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script><script>var userList = new Array();userList.push({username:"zhangsan",age:18});userList.push({username:"lisi",age:28});$.ajax({type:"POST",url:"${pageContext.request.contextPath}/user/quick15",data:JSON.stringify(userList),contentType:"application/json;charset=utf-8"});</script>
@RequestMapping(value="/quick15")@ResponseBodypublic void save15(@RequestBody List<User> userList) throws IOException {System.out.println(userList);}

2.7 SpringMVC的请求-获得请求参数-静态资源访问的开启(应用)

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

•在spring-mvc.xml配置文件中指定放行的资源

<mvc:resources mapping="/js/**"location="/js/"/>

•使用<mvc:default-servlet-handler/>标签

<!--开发资源的访问--><!--<mvc:resources mapping="/js/**" location="/js/"/><mvc:resources mapping="/img/**" location="/img/"/>--><mvc:default-servlet-handler/>

2.8 SpringMVC的请求-获得请求参数-配置全局乱码过滤器(应用)

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

<!--配置全局过滤的filter--><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

2.9 SpringMVC的请求-获得请求参数-参数绑定注解@RequestParam(应用)

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

<form action="${pageContext.request.contextPath}/quick16" method="post"><input type="text" name="name"><br><input type="submit" value="提交"><br>
</form>
@RequestMapping(value="/quick16")@ResponseBodypublic void save16(@RequestParam(value="name",required = false,defaultValue = "itcast") String username) throws IOException {System.out.println(username);}

2.10 SpringMVC的请求-获得请求参数-Restful风格的参数的获取(应用)

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

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

GET:用于获取资源

POST:用于新建资源

PUT:用于更新资源

DELETE:用于删除资源

例如:

/user/1 GET : 得到 id = 1 的 user

/user/1 DELETE: 删除 id = 1 的 user

/user/1 PUT: 更新 id = 1 的 user

/user POST: 新增 user

上述url地址/user/1中的1就是要获得的请求参数,在SpringMVC中可以使用占位符进行参数绑定。地址/user/1可以写成/user/{id},占位符{id}对应的就是1的值。在业务方法中我们可以使用@PathVariable注解进行占位符的匹配获取工作。

http://localhost:8080/itheima_springmvc1/quick17/zhangsan

@RequestMapping(value="/quick17/{name}")
@ResponseBodypublic void save17(@PathVariable(value="name") String username) throws IOException {System.out.println(username);}

2.11 SpringMVC的请求-获得请求参数-自定义类型转换器(应用)

SpringMVC 默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置。

但是不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,例如:日期类型的数据就需要自定义转换器。

public class DateConverter implements Converter<String, Date> {public Date convert(String dateStr) {//将日期字符串转换成日期对象 返回SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");Date date = null;try {date = format.parse(dateStr);} catch (ParseException e) {e.printStackTrace();}return date;}
}
@RequestMapping(value="/quick18")@ResponseBodypublic void save18(Date date) throws IOException {System.out.println(date);}

2.12 SpringMVC的请求-获得请求参数-获得Servlet相关API(应用)

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

HttpServletRequest

HttpServletResponse

HttpSession

@RequestMapping(value="/quick19")@ResponseBodypublic void save19(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {System.out.println(request);System.out.println(response);System.out.println(session);}

2.13 SpringMVC的请求-获得请求参数-获得请求头信息(应用)

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

@RequestHeader注解的属性如下:

value:请求头的名称

required:是否必须携带此请求头

@RequestMapping(value="/quick20")@ResponseBodypublic void save20(@RequestHeader(value = "User-Agent",required = false) String user_agent) throws IOException {System.out.println(user_agent);}

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

@CookieValue注解的属性如下:

value:指定cookie的名称

required:是否必须携带此cookie

 @RequestMapping(value="/quick21")@ResponseBodypublic void save21(@CookieValue(value = "JSESSIONID") String jsessionId) throws IOException {System.out.println(jsessionId);}

三、SpringMVC的文件上传、拦截器及异常处理

1. SpringMVC的文件上传

1.1 SpringMVC的请求-文件上传-客户端表单实现(应用)

文件上传客户端表单需要满足:

表单项type=“file”

表单的提交方式是post

表单的enctype属性是多部分表单形式,及enctype=“multipart/form-data”

<form action="${pageContext.request.contextPath}/user/quick22" method="post" enctype="multipart/form-data">名称<input type="text" name="username"><br/>文件1<input type="file" name="uploadFile"><br/><input type="submit" value="提交"></form>

1.2 pringMVC的请求-文件上传-文件上传的原理(理解)

1.3 SpringMVC的请求-文件上传-单文件上传的代码实现1(应用)

添加依赖

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

配置多媒体解析器

<!--配置文件上传解析器--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="defaultEncoding" value="UYF-8"/><property name="maxUploadSize" value="500000"/></bean>

后台程序

@RequestMapping(value="/quick22")@ResponseBodypublic void save22(String username, MultipartFile uploadFile) throws IOException {System.out.println(username);System.out.println(uploadFile);}

1.4 SpringMVC的请求-文件上传-单文件上传的代码实现2(应用)

完成文件上传

@RequestMapping(value="/quick22")@ResponseBodypublic void save22(String username, MultipartFile uploadFile) throws IOException {System.out.println(username);//获得上传文件的名称String originalFilename = uploadFile.getOriginalFilename();uploadFile.transferTo(new File("C:\\upload\\"+originalFilename));}

1.5 SpringMVC的请求-文件上传-多文件上传的代码实现(应用)

多文件上传,只需要将页面修改为多个文件上传项,将方法参数MultipartFile类型修改为MultipartFile[]即可

<form action="${pageContext.request.contextPath}/user/quick23" method="post" enctype="multipart/form-data">名称<input type="text" name="username"><br/>文件1<input type="file" name="uploadFile"><br/>文件2<input type="file" name="uploadFile"><br/><input type="submit" value="提交"></form>
@RequestMapping(value="/quick23")@ResponseBodypublic void save23(String username, MultipartFile[] uploadFile) throws IOException {System.out.println(username);for (MultipartFile multipartFile : uploadFile) {String originalFilename = multipartFile.getOriginalFilename();multipartFile.transferTo(new File("C:\\upload\\"+originalFilename));}}

1.6 SpringMVC的请求-知识要点(理解,记忆)

2. SpringMVC的拦截器

2.1 SpringMVC拦截器-拦截器的作用(理解)

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

将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(InterceptorChain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。

2.2 SpringMVC拦截器-interceptor和filter区别(理解,记忆)

关于interceptor和filter的区别,如图所示:

2.3 SpringMVC拦截器-快速入门(应用)

自定义拦截器很简单,只有如下三步:

①创建拦截器类实现HandlerInterceptor接口

②配置拦截器

③测试拦截器的拦截效果

编写拦截器:

public class MyInterceptor1 implements HandlerInterceptor {//在目标方法执行之前 执行public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {System.out.println("preHandle.....");
}//在目标方法执行之后 视图对象返回之前执行public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {System.out.println("postHandle...");}//在流程都执行完毕后 执行public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {System.out.println("afterCompletion....");}
}

配置:在SpringMVC的配置文件中配置

<!--配置拦截器--><mvc:interceptors><mvc:interceptor><!--对哪些资源执行拦截操作--><mvc:mapping path="/**"/><bean class="com.itheima.interceptor.MyInterceptor1"/></mvc:interceptor></mvc:interceptors>

编写测试程序测试:

编写Controller,发请求到controller,跳转页面

@Controller
public class TargetController {@RequestMapping("/target")public ModelAndView show(){System.out.println("目标资源执行......");ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("name","itcast");modelAndView.setViewName("index");return modelAndView;}}

页面

<html>
<body>
<h2>Hello World! ${name}</h2>
</body>
</html>

2.4 SpringMVC拦截器-快速入门详解(应用)

拦截器在预处理后什么情况下会执行目标资源,什么情况下不执行目标资源,以及在有多个拦截器的情况下拦截器的执行顺序是什么?

再编写一个拦截器2,

public class MyInterceptor2 implements HandlerInterceptor {//在目标方法执行之前 执行public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {System.out.println("preHandle22222.....");return true;}//在目标方法执行之后 视图对象返回之前执行public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {System.out.println("postHandle2222...");}//在流程都执行完毕后 执行public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {System.out.println("afterCompletion2222....");}
}

配置拦截器2

<!--配置拦截器--><mvc:interceptors><mvc:interceptor><!--对哪些资源执行拦截操作--><mvc:mapping path="/**"/><bean class="com.itheima.interceptor.MyInterceptor2"/></mvc:interceptor><mvc:interceptor><!--对哪些资源执行拦截操作--><mvc:mapping path="/**"/><bean class="com.itheima.interceptor.MyInterceptor1"/></mvc:interceptor></mvc:interceptors>

结论:

当拦截器的preHandle方法返回true则会执行目标资源,如果返回false则不执行目标资源

多个拦截器情况下,配置在前的先执行,配置在后的后执行

拦截器中的方法执行顺序是:preHandler-------目标资源----postHandle---- afterCompletion

2.5 SpringMVC拦截器-知识小结(记忆)

拦截器中的方法说明如下


2.6 SpringMVC拦截器-用户登录权限控制分析(理解)

在day06-Spring练习案例的基础之上:用户没有登录的情况下,不能对后台菜单进行访问操作,点击菜单跳转到登录页面,只有用户登录成功后才能进行后台功能的操作

需求图:

在这里插入图片描述

2.7 SpringMVC拦截器-用户登录权限控制代码实现1(应用)

判断用户是否登录 本质:判断session中有没有user,如果没有登陆则先去登陆,如果已经登陆则直接放行访问目标资源

先编写拦截器如下:

public class PrivilegeInterceptor implements HandlerInterceptor {public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {//逻辑:判断用户是否登录  本质:判断session中有没有userHttpSession session = request.getSession();User user = (User) session.getAttribute("user");if(user==null){//没有登录response.sendRedirect(request.getContextPath()+"/login.jsp");return false;}//放行  访问目标资源return true;}
}

然后配置该拦截器:找到项目案例的spring-mvc.xml,添加如下配置:

<!--配置权限拦截器--><mvc:interceptors><mvc:interceptor><!--配置对哪些资源执行拦截操作--><mvc:mapping path="/**"/><bean class="com.itheima.interceptor.PrivilegeInterceptor"/></mvc:interceptor></mvc:interceptors>

2.8 SpringMVC拦截器-用户登录权限控制代码实现2(应用)

在登陆页面输入用户名密码,点击登陆,通过用户名密码进行查询,如果登陆成功,则将用户信息实体存入session,然后跳转到首页,如果登陆失败则继续回到登陆页面

在UserController中编写登陆逻辑

@RequestMapping("/login")public String login(String username,String password,HttpSession session){User user = userService.login(username,password);if(user!=null){//登录成功  将user存储到sessionsession.setAttribute("user",user);return "redirect:/index.jsp";}return "redirect:/login.jsp";}

service层代码如下:

//service层
public User login(String username, String password) {User user = userDao.findByUsernameAndPassword(username,password);return user;
}

dao层代码如下:

//dao层public User findByUsernameAndPassword(String username, String password) throws EmptyResultDataAccessException{User user = jdbcTemplate.queryForObject("select * from sys_user where username=? and password=?", new BeanPropertyRowMapper<User>(User.class), username, password);return user;}

此时仍然登陆不上,因为我们需要将登陆请求url让拦截器放行,添加资源排除的配置

<!--配置权限拦截器--><mvc:interceptors><mvc:interceptor><!--配置对哪些资源执行拦截操作--><mvc:mapping path="/**"/><!--配置哪些资源排除拦截操作--><mvc:exclude-mapping path="/user/login"/><bean class="com.itheima.interceptor.PrivilegeInterceptor"/></mvc:interceptor></mvc:interceptors>

2.9 SpringMVC拦截器-用户登录权限控制代码实现3(应用)

JdbcTemplate.queryForObject对象如果查询不到数据会抛异常,导致程序无法达到预期效果,如何来解决该问题?

在业务层处理来自dao层的异常,如果出现异常service层返回null,而不是将异常抛给controller

因此改造登陆的业务层代码,添加异常的控制

public User login(String username, String password) {try {User user = userDao.findByUsernameAndPassword(username,password);return user;}catch (EmptyResultDataAccessException e){return null;}}

3. SpringMVC异常处理机制

3.1 异常处理的思路

系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试等手段减少运行时异常的发生。

系统的Dao、Service、Controller出现都通过throws Exception向上抛出,最后由SpringMVC前端控制器交由异常处理器进行异常处理,如下图:

3.2 异常处理两种方式

① 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver

② 实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器

3.3 简单异常处理器SimpleMappingExceptionResolver

SpringMVC已经定义好了该类型转换器,在使用时可以根据项目情况进行相应异常与视图的映射配置

<!--配置简单映射异常处理器--><bean class=“org.springframework.web.servlet.handler.SimpleMappingExceptionResolver”>    <property name=“defaultErrorView” value=“error”/>   默认错误视图<property name=“exceptionMappings”><map>      异常类型                                     错误视图<entry key="com.itheima.exception.MyException" value="error"/><entry key="java.lang.ClassCastException" value="error"/></map></property>
</bean>

3.4 自定义异常处理步骤

①创建异常处理器类实现HandlerExceptionResolver

public class MyExceptionResolver implements HandlerExceptionResolver {@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {//处理异常的代码实现//创建ModelAndView对象ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("exceptionPage");return modelAndView;}
}

②配置异常处理器

<bean id="exceptionResolver"        class="com.itheima.exception.MyExceptionResolver"/>

③编写异常页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>这是一个最终异常的显示页面
</body>
</html>

④测试异常跳转

@RequestMapping("/quick22")
@ResponseBody
public void quickMethod22() throws IOException, ParseException {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); simpleDateFormat.parse("abcde");
}

3.5 知识要点

异常处理方式

① 配置简单异常处理器SimpleMappingExceptionResolver

② 自定义异常处理器

自定义异常处理步骤

①创建异常处理器类实现HandlerExceptionResolver

②配置异常处理器

③编写异常页面

④测试异常跳转

Java进阶:SpringMVC相关推荐

  1. 《Java 进阶之路》 下--推荐书籍

    真正想提升自己,我感觉最主要的是先把 JVM.并发.网络这三块知识点学会.学通,这三块是基础,后面所有的框架.中间件等相关的都是基于这三块知识点之上的.学完这三块知识点,可以快速的掌握其它的知识,新框 ...

  2. 【转】【Books】史上最全的Java进阶书籍推荐

    [转载] 学习Java,书籍是必不可少的学习工具之一,尤其是对于自学者而言.废话不多说,下边就给大家推荐一些Java进阶的好书. 第一部分:Java语言篇 1.<Java编程规范> 适合对 ...

  3. 【书籍学习】史上最全的Java进阶书籍推荐

    学习Java,书籍是必不可少的学习工具之一,尤其是对于自学者而言.废话不多说,下边就给大家推荐一些Java进阶的好书. 第一部分:Java语言篇 1.<Java编程规范> 适合对象:初级. ...

  4. Java进阶基础知识

    Java进阶基础知识 1.Java 基础 Java类设计的原则就是内聚性,一致性和封装性是Java设计的基本原则 1.1 Java基础理论 Java基础理论知识 1.2继承的优缺点 1.2.1优点 : ...

  5. 绝~ 阿里内部“Java进阶必备宝典”,理论到实战,一键通关

    前言 作为一名Java方向的程序员,打好夯实的基础是非常重要的,现在大厂面试对于程序员基础知识的掌握考察也越来越严格,虽然说现在技术更新比较快,但基础扎实才能够更深入的去理解每一个知识技术点. 关于J ...

  6. java B2B2C springmvc mybatis电子商务平台源码-Consul服务发现原理...

    Consul 是什么 Consul 是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件,由 HashiCorp 公司用 Go 语言开发, 基于 Mozilla Public License ...

  7. java多图片上传json_[Java教程]SpringMVC框架五:图片上传与JSON交互

    [Java教程]SpringMVC框架五:图片上传与JSON交互 0 2018-08-07 22:00:42 在正式图片上传之前,先处理一个细节问题: 每一次发布项目,Tomcat都会重新解压war包 ...

  8. Java进阶(五)Java I/O模型从BIO到NIO和Reactor模式

    本文介绍了Java中的四种I/O模型,同步阻塞,同步非阻塞,多路复用,异步阻塞.同时将NIO和BIO进行了对比,并详细分析了基于NIO的Reactor模式,包括经典单线程模型以及多线程模式和多Reac ...

  9. java spring省略jsp,Java +Tomcat + SpringMVC实现页面访问示例解析

    window7下Java环境安装记录: 一.安装Tomcat 1.下载tomcat 7.0,解压,无需安装,放置到目录:D:\apache-tomcat-7.0.90. 2.配置系统环境变量,CATA ...

  10. Java 进阶 ——2019 计划要读的书

    Java 进阶 --2019 计划要读的书 代码整洁之道 重构 这两本学习完再写下面的书

最新文章

  1. sqlserver查询一个表的字段信息
  2. access中判断回文的代码_LeetCode 第九题 回文数
  3. android - FlutterActivity MethodChannel和FlutterView
  4. 延边大学c语言题库,延边大学-SPOC官方网站
  5. Java只用一个循环语句输出九九乘法表
  6. xftp、xshell连接远程服务器,所选的用户密钥未在远程主机上注册
  7. 压力测试工具之DDos-Attack
  8. 拓端tecdat|matlab如何滤除低频尖峰脉冲
  9. DM7数据库安装图文教程
  10. 3D建模、处理软件及部分算法库简介
  11. Spring Value注解的使用
  12. ISUP信令REL原因值
  13. linux连接小米随身wifi密码忘记了,小米路由器无线密码(wifi密码)忘记了怎么办?...
  14. QA是干什么的?(职责所在????)
  15. 简单网页版的年会抽奖程序,设计个界面套上就可以了,抽奖员工编号姓名改改代码就可以了,很简单的
  16. ARP攻击--(ArpSpoof 欺骗工具)
  17. ABP EF Core多数据库支持
  18. java dispo lock_java
  19. rc时间常数定义_时间常数τ(tao)=RC和周期T有什么关系?
  20. 【C语言】给出一百分制成绩,要求输出成绩等级

热门文章

  1. 13.深入分布式缓存:从原理到实践 --- 缓存在社交网络Feed系统中的架构实践
  2. 11.GitLab webhooks
  3. 5. Linux 设备文件名
  4. 62. Event shiftKey 事件属性
  5. Attention Please
  6. ElectronNetTest
  7. luogu_P4767 [IOI2000]邮局
  8. Java:根据二叉树的前序,中序遍历构造二叉树
  9. STL之pair及其非成员函数make_pair()
  10. 3137102432_施少兵_实验2