一、SpringMVC简介:
1、什么是MVC:
MVC是一种架构模型,本身没有什么功能,只是让我们的项目结构更加合理,流程控制更加清晰,一般包含三个组件:
Model(模型):数据模型,用于提供要展示的数据。一般包含数据和行为(也就是业务),在JavaWEB中,数据和业务往往是分离开的。
View(视图):负责对模型数据进行展示,例如我们看到的网页。概念比较广泛,可以是:html、JSP、excel、Word、PDF、json、XML等
Controller(控制器):接收用户请求,委托给模型做处理,处理完毕返回数据,再交给视图做渲染,相当于调度员工作。
2、什么是SpringMVC:
首先,SpringMVC是Spring架构中的一部分,基于Java的实现了Web MVC 设计模式的轻量级Web框架。其次,使用了MVC架构模式的思想,解耦了web层的耦合关系,更具有扩展性和灵活性。
作用:①进行更简洁的Web层的开发;
②天生与Spring框架集成(如IoC容器、AOP等);
③提供强大的约定大于配置的契约式编程支持;
④支持灵活的URL到页面控制器的映射;
⑤非常容易与其他视图技术集成,如Velocity、FreeMarker等等,因为模型数据不放在特定的API里,而是放在一个Model里(Map数据结构实现,因此很容易被其他框架使用);
⑥非常灵活的数据验证、格式化和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的API;
⑦支持Restful风格。
3、SpringMVC的架构:
流程总结:
1.用户发起请求到DispatcherServlet(前端控制器)
2.DispatcherServlet通过HandlerMapping(处理映射器)寻找用户要请求的Handler
3.HandlerMapping返回执行链,包含两部分内容:
①处理器对象:Handler
②HandlerInterceptor(拦截器)的集合
4.前端控制器通过HandlerAdapter(处理器适配器)对Handler进行适配包装
5.调用包装后的Handler中的方法,处理业务
6.处理业务完成,返回ModelAndView对象,包含两部分:
①Model:模型数据
②View:视图名称,不是真正的视图
7.DispatcherServlet获取处理得到的ModelAndView对象
8.DispatcherServlet将视图名称交给ViewResolver(视图解析器),查找视图
9.ViewResolver返回真正的视图对象给DispatcherServlet
10.DispatcherServlet把Model(数据模型)交给视图对象进行渲染
11.返回渲染后的视图
12.将最终的视图返回用户,产生响应
二、SpringMVC的入门案例:
1、创建项目,引入父工程
2、引入依赖,坐标
<dependencies>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
</dependencies>
3、配置Tomcat插件:tomcat7
<build>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<!-- 端口信息 -->
<port>8080</port>
<!-- 项目路径 -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
4、编写项目配置文件:1)web.xml,引入DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="MyWebApp" version="2.5">
<display-name>springMVC</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<!--在web.xml(web程序的入口) 配置了DispatcherServlet,并且指定所有以.do结尾的请求全部交给DispatcherServlet来处理-->
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 配置/*会拦截所有请求,包括静态页面 -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
2)springmvc的配置文件:springmvc-servlet.xml
①配置HandlerMapping(可省略)
②配置HandlerAdapter(可省略)
③配置Handler
④配置视图解析器
3)定义视图:XXX.jsp 测试
4)执行流程分析、SpringMVC默认配置(默认配置文件中有HandlerMapping和HandlerAdapter)
三、SpringMVC注解案例:
1、创建注解控制器(Controller)
2、配置包扫描:<context:component-scan base-package="包路径" />
3、测试
4、默认配置的问题及推荐方案
5、注解驱动及原理:<mvc:annotation-driven />
6、总结:1)开启注解驱动<mvc:annotation-driven/>
2)开启扫描包
3)配置内部资源解析器:视图解析器
四、RequestMapping请求映射方式:
1、标准映射:①@RequestMapping()可以设置在类上,也可以设置在方法上
②请求的映射规则是:类上的RequestMapping + 方法上的RequestMapping
③如果没有写 / ,SpringMVC会自动补全
④类上的RequestMapping可以省略,这时直接用方法的RequestMapping访问
⑤路径不可重复
2、Ant风格映射:通配符映射3种:? 匹配一个字符,* 匹配零个或多个字符,** 匹配零个或多个路径
3、占位符映射--常用:@PathVariable()
4、请求方式限定:method={RequestMethod.POST,RequestMethod.GET}
5、请求参数限定:@RequestParam()
五、视图解析:
1、什么是视图:视图就是展示给用户看的结果。可以是很多形式,例如:html、JSP、excel表单、Word文档、PDF文档、JSON数据、freemarker模板视图等等。
2、传统JSP和JSTL视图:常用的InternalResourceViewResolver解析器,默认支持JSP视图,而JSP中最常用的莫过于JSTL标签库了。
3、JSON视图:①引入依赖:SpringMVC的JSON功能,底层依赖的是Jackson这个JSON工具。
<!-- Jackson Json处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
②定义controller:@ResponseBody将返回值转成json,异步请求
③访问测试
原理:
1)当SpringMVC读取到方法上的@ResponseBody注解时,就知道该方法不再使用默认的视图解析器解析视图,而是直接把结果写到响应体中,这样就需要对结果进行转换。
2)SpringMVC会从框架中查找有没有定义MessageConvertor(消息转换器),通过消息转换器转换结果,返回对应视图。
3)在SpringMVC的注解驱动类中,会进行默认的消息转换器注册,因为我们引入了jacksonJson包,所以会注册JSON的消息转换器。
4)因为只有JSON消息转换器可以对Java对象序列化,因此这里默认用了JSON转换。
4、直接返回视图名称:String数据
5、重定向和转发:redirect:/*.do 重定向到*.do
forward:/*.do 转发到*.do
注意:后面必须跟上URL路径而非视图名。
返回ModelAndView,或者没有写redirect和forward时,默认都属于转发。
6、不返回视图:@ResponseStatus,异步请求
六、请求参数绑定和获取:
1、获取servlet内置对象
2、获取PathVariable参数:占位符映射 == 占位符传参 最常用 1.无须进行参数必须的声明 2.无须进行参数校验
注意:参数类型必须匹配,否则会出错
3、获取基本数据类型请求参数:@RequestParam声明一个必须的参数
4、获取请求参数并封装为POJO对象
5、RequestParam的更多用法:默认required为true,需给定参数;设置required为false,并且给定一个默认值。
@RequestParam(value="pageNum",required="true",defaultValue="1")
6、获取cookie值:@CookieValue("JSESSIONID")
7、接收对象List集合
8、接收JSON格式请求:①接收单个User对象
②接收JSON的数组:@ResponseBody 是把返回值的Pojo对象变为JSON字符串,称为序列化
@RequestBody 是把接收到的JSON字符串变为Pojo对象,称为反序列化
七、SpringMVC和Struts的区别:
1、入口不同:Servlet;Filter。
2、设计不同:方法设计,方法形参,单例,性能高;类设计,类的属性,多例。
3、参数传递:基于方法,多个方法不能共享;基于类的属性,多个方法可以共享。
八、文件上传:SpringMVC的文件上传,底层也是使用的Apache的Commons-fileupload。
1、引入依赖包:
<!-- 文件上传的依赖 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
2、在xxx-serlvet.xml中添加文件上传的解析器:
<!-- 定义文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设定默认编码 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 设定文件上传的最大值5MB,5*1024*1024 -->
<property name="maxUploadSize" value="5242880"></property>
</bean>
3、编写controller控制器
@RequestMapping("/test")
// 通过参数:MultipartFile file来接收上传的文件,这个是SpringMVC中定义的类,会被自动注入
public ModelAndView show21(@RequestParam("file") MultipartFile file) throws Exception {
ModelAndView mv = new ModelAndView("hello");
if(file != null){
// 将上传得到的文件 转移到指定文件。
file.transferTo(new File("D:/test/" + file.getOriginalFilename()));
}
mv.addObject("msg", "上传成功!" + file.getOriginalFilename());
return mv;
}
九、拦截器:
1、HandlerExecutionChain回顾:
HandlerExecutionChain是一个执行链,当用户的请求到达DispatcherServlet的时候,DispatcherServlet会到HandlerMapping中查找对应的Handler,找到后返回的就是这个:HandlerExecutionChain,里面包含了:
①正确的Handler对象
②Handler的拦截器集合,这里的拦截器对象是:HandlerInterceptor
2、拦截器接口:HandlerInterceptor三个方法
preHandle:预处理回调方法,在Handler执行前执行,第三个参数为处理器(Controller 实现);
返回值:true 表示继续流程(如调用下一个拦截器或处理器);
false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器;
postHandle :后处理回调方法,实现处理器的后处理(但在渲染视图之前)
afterCompletion: :整个请求处理完毕回调方法,即在视图渲染完毕时回调
当然,这个接口还有一个适配器类:HandlerInterceptorAdapter,对三个方法进行了空实现。我们可以有选择的重写想要实现的方法。
3、拦截器执行顺序
4、自定义拦截器:自定义拦截器实现HandlerInterceptor接口
5、配置自定义拦截器
6、测试总结:
①拦截器的前置方法顺序执行,如果返回true,继续。返回false,流程终止,执行前面所有返回true的拦截器的完成方法
②拦截器的后置方法倒序执行,在Controller执行结束后,视图解析前执行。
③拦截器的完成后方法倒序执行,在视图解析后执行。无论前面是否出错或返回false,已经执行过的拦截器的完成方法都会被执行,类似于finally
十、通用异常处理:
1、异常处理思路
2、自定义异常
3、在Controller中模拟异常
4、定义异常处理器
5、配置自定义异常处理器
6、定义通用异常页面
7、测试结果
8、注解方式定义通用异常处理:
@ControllerAdvice,定义在类上
@ExceptionHandler 异常处理器,定义在方法上,这个方法就是专门做异常处理的方法。其value属性是Class数组,用来指定处理的异常类型,如果为空,那么默认处理所有的异常类型
9、测试结果