thymeleaf和视图解析
1.html上加:xmlns:th=”http://www.thymeleaf.org“
2.th:href里 @{}和${}的区别
3.不用写前缀后缀
4.行内写法 [[${}]]
5.session可以直接用
这里就写作session,和controller session叫什么无关。 最后总会通过Response重新封装session的
拦截器
1.DispatcherServlet # doDispatch() -> HandlerExecutionChain # applyPreHandle() -> 遍历所有的拦截器,遍历的第一个拦截器是我们自定义的,如果我们的拦截器拦到了而且没有定义转发的话,那么整个请求就会停止。这里是i++,顺序执行所有拦截器
上面方法里的interceptorIndex是给下面的 triggerAfterCompletion() 用的
2.如果定义了转发,就会转发到特定的页面。
这个转发过程会重新从头开始走一遍和上面一模一样的流程,只不过这个请求不会前面那样拦截并转发,而是拦截并放行
转发到新页面,也相当于调用了新的controller层的方法。转发请求同样会被拦截器拦截,只不过最后被放行了。然后就是正常的处理controller层的方法的流程了(handleMapping封装handler,处理参数,处理返回值,解析页面,跳转页面·····)
3.如果被拦截了,并且preHandler里没有转发或重定向,那么就会接着执行triggerAfterCompletion()方法,目的是执行的拦截器的afterCompletion(),不过这是里 i—,相当于倒序执行所有的拦截器
4.如果所有拦截器,都放心,那么接下来执行目标方法,返回结果封装成mv,
5.然后倒序执行,所有拦截器的postHandler方法
6.上面发生了任何异常,都会直接触发所有拦截器的afterCompletion()方法
如果页面渲染正常,最后也会触发afterCompletion()。(注意,这里藏在了processDispatchResult())
这个方法都是倒序执行拦截器
文件上传
如果chrome里面有input的type为text的输入框,有输入记录,无法删除,用shift+del删除
1.前端写法:用input,type=file。 如果是多文件就加上 multiple
<div class="form-group">
<label for="exampleInputFile">头像</label>
<input type="file" name="headImage">
</div>
<div class="form-group">
<label for="exampleInputFile">生活照</label>
<input type="file" name="photos" multiple>
</div>
<form role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data">
form表单要加上 enctype=”multipart/form-data”
2.参数接受写法: 注解用@RequestPart,类型用MultipartFile,如果是多文件,就用数组 MultipartFile[]
3.使用方法:参数解析有很多种方法,比如直接得到原生文件名、直接使用transferTo存在磁盘上。注意,比如new File的时候,磁盘的路径必须有 \ 进行转义,而且保存前,必须先判断文件是否存在,这步很重要
文件上传原理
首先检查请求是否是文件上传请求。怎么检查?checkMultipart里,用文件解析器的isMultipart()方法判断是否是文件上传请求。
文件解析器只有一个:标准Servlet文件解析器。
isMultipart()方法也很简单,获取 request的内容类型,用StringUtils这个工具类判断是否是multipart开头(忽略大小写)。
这里因为我们的form表单的enctype=“multipart/form-data”,所以判断为true
然后就是正正常流程了,adapter调用handler方法解析,目的是为了获得ModelAndView
这个handle的过程,会设计到参数解析。参数解析最后发现用了 RequestPartMethodArgumentResolver这个解析器,进入他的resolveArgument(),经过上面显示的一些复杂的过程吧,最后返回的是
AbstractMultipartHttpServletRequest的multipartFiles的value(因为他是个Map,所以根据key返回value)
这个value是MultipartFile类型的。
所以说明最后参数MultipartFile的初始化也是MultipartFile。
文件自动配置原理
文件上传自动配置类:MultipartAutoConfiguration - MultipartProperties
- 自动配置好了 StandardServletMultipartResolver 【文件上传解析器】
- 原理步骤
- 1、请求进来使用文件上传解析器判断(isMultipart)并封装(resolveMultipart,返回MultipartHttpServletRequest)文件上传请求
- 2、参数解析器来解析请求中的文件内容封装成MultipartFile
- 3、将request中文件信息封装为一个Map;MultiValueMap
transferTo()方法
MultipartFile: 接口
继承关系
行为:获取名字getName()、获取字节getBytes()、获取原生名getOriginalFilename()、获取大小getResource()、转化transferTo()等
行为有很多
重点看一下 transferTo():用到了FileCopyUtils。这是个文件工具类。功能很强大,以后可以看着用用