1.内容介绍
- 文件上传 – 通过springmvc的方式
- 拦截器
- 异常处理
2.SpringMVC的文件上传
2.1. 文件上传-客户端表单实现
文件上传客户端表单需要满足:
- form表单的enctype取值必须是:multipart/form-data ;
(默认值是:application/x-www-form-urlencoded) enctype:是表单请求正文的类型 - method属性取值必须是Post
- 提供一个文件选择域
文件上传三要素:
上传方式:
- 传统方式 : 从request域中取;
- Springmvc方式上传 : MultipartFile upload
(框架帮我们从request域中取出并且封装进MultipartFile 对象)
2.2. 文件上传-文件上传的原理
2.3. 文件上传-单文件上传的代码实现
步骤:
① 导入fileupload和io坐标
② 配置文件上传解析器
③ 编写文件上传代码
添加依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
配置文件上传解析器
<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<property name="maxUploadSize" value="500000"/>
</bean>
后台程序
2.4. 文件上传-多文件上传的代码实现
多文件上传,只需要将页面修改为多个文件上传项,将方法参数MultipartFile类型修改为MultipartFile[]即可
常见错误:
文件大小超过限制:
指定文件大小
文件上传的表单三要素:
Method = post
enctype="multipart/form-data"
Type=file
3.SpringMVC的拦截器
3.1. 拦截器-拦截器的作用
- Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。
- 将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(InterceptorChain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。
3.2. 拦截器-interceptor和filter区别
拦截器和过滤器的功能比较类似,有区别:
- 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
- 拦截器是SpringMVC框架独有的。
- 过滤器配置了/*,可以拦截任何资源。 ---- 静态资源和动态资源都能拦截
- 拦截器只会对控制器中的方法进行拦截。 ---- 只能拦截控制器中的方法(controller的方法)
拦截器也是AOP思想的一种实现方式
想要自定义拦截器,需要实现HandlerInterceptor接口。
3.3. 拦截器-快速入门
自定义拦截器很简单,只有如下三步:
- ①创建拦截器类实现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,跳转页面
测试结果:
执行顺序
3.4. 拦截器-快速入门详解
拦截器在预处理后什么情况下会执行目标资源,什么情况下不执行目标资源,以及在有多个拦截器的情况下拦截器的执行顺序是什么?
结论:
- 当拦截器的preHandle方法返回true则会执行目标资源,如果返回false则不执行目标资源
- 多个拦截器情况下,配置在前的先执行,配置在后的后执行
- 拦截器中的方法执行顺序是:preHandler-------目标资源----postHandle---- afterCompletion
方法名 | 说明 |
---|---|
preHandle() | 方法将在请求处理之前进行调用,该方法的返回值是布尔值Boolean类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法 |
postHandle() | 该方法是在当前请求进行处理之后被调用,前提是preHandle 方法的返回值为true 时才能被调用,且它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作 |
afterCompletion() | 该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行,前提是preHandle 方法的返回值为true 时才能被调用 |
注意:
拦截器三个方法的执行时机, 不同的执行时机,会有不同的功能!
- preHandle(): 在真正访问目标资源前,对用户的请求进行 校验, 符合条件才放行! 比如: 登录。
- postHandle(): 在目标资源访问结束以后,返回客户端前,执行。 比如: 对结果进行增加, 根据不同的结果,进行不同的跳转;
- afterCompletion(): 所有执行结束以后,执行(响应客户端以后)。 比如:短信提醒、 邮件提醒… (不论成功还是失败)
3.5. 补充:拦截器-知识小结
拦截器的放行
放行的含义是指,如果有下一个拦截器就执行下一个,如果该拦截器处于拦截器链的最后一个,则执行控制器中的方法。
拦截器中方法的说明
-
preHandle()
是controller方法执行前拦截的方法 — 预处理 — 通常可以校验用户是否登录, 参数校验、 设置编码。。。。- 可以使用request或者response跳转到指定的页面
- return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
- return false不放行,不会执行controller中的方法。
-
postHandle()
是controller方法执行后执行的方法,在JSP视图执行前。 — 后处理 — 设置响应编码… 或者打印日志…- 可以使用request或者response跳转到指定的页面
- 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
-
afterCompletion()
方法是在JSP执行后执行 -------- 响应后,最终执行的操作, ---- 可以释放资源 或者 发送短信、邮件、记录日志等等!- request或者response不能再跳转页面了
拦截器的作用路径
<mvc:interceptor>
<!--
配置拦截器拦截的方法
/** 代表拦截所有方法
/user/* 代表拦截/user路径下的所有方法
-->
<mvc:mapping path="/user/*"/>
<!--配置不拦截的方法
<mvc:exclude-mapping path="/img/**" />
-->
<bean id="myInterceptor1" class="com.itheima.interceptor.MyInterceptor1"></bean>
</mvc:interceptor>
4. SpringMVC异常处理机制
系统中异常包括两类:
- 预期异常
- 运行时异常RuntimeException
4.1. 异常处理的思路
系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试等手段减少运行时异常的发生。
系统的Dao、Service、Controller出现都通过throws Exception向上抛出,最后由SpringMVC前端控制器交由异常处理器进行异常处理,如下图:
在dao、service可以往外抛, 在controller一般来说必须处理 (不能把异常抛给用户)
4.2. 异常处理两种方式
① 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver
② 实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器
4.3. 简单异常处理器SimpleMappingExceptionResolver
SpringMVC已经定义好了该类型转换器,在使用时可以根据项目情况进行相应异常与视图的映射配置
4.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");
}
出现异常后的流程:
当配置了异常处理器以后, 一旦controller抛出了异常, dispatcherServlet就会去调用自定义的异常处理器完成对异常的处理!
自定义异常处理器: 就是返回 良好的提示信息和视图----- 指定的提示页面(用户就看不见404和500…)
拓展延伸:
关于404:
一些网站的做法
关于网络不稳定: