29 SpringMVC 上传文件未生成临时文件
2017-12-02 17:34
204 查看
这个问题, 是这样的 : js ajax提交上传一个文件 到服务器1, 然后 服务器1需要吧文件 上传到服务器2, 差不多就是这个流程
js传递文件到服务器1之后, 通过 HttpClient 的MultipartEntityBuilder, post 服务器1生成的临时文件[file.getFile().getFileItem().getStoreLocation()], 发送到 服务器2, 然后 服务器2接收, 持久化 以及处理响应的业务逻辑
然后 这样的处理方式, 在我自己开发测试的时候, 发现 上传文件是能够上传成功, 然后 之后过了几天, 再来测试, 却发现 上传文件上传不成功了,
然后 查询了一下后面 服务器1的日志, 发现 报的是一个 FNFE, 然后 瞅了一下该临时文件存储的地方, 妈的 居然刚上传的图片没有临时文件生成
然后 网上搜索了一下, 最后 网上搜索了一篇文章, 然后 配置了一下, 临时解决了这个问题, 然后 是准备 周末瞅瞅这块的代码
spring mvc做上传图片,文件小于10k就不生成临时文件了 : http://ask.csdn.net/questions/191012
然后 接下来是正题了, CommonsMultipartResolver 解析请求的流程,
环境 : spring-* : 4.2.5 RELEASE, commons-* : 2.4
FileUploadBase. parseRequest
![](https://img-blog.csdn.net/20171202172929688?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTAzOTMzMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
在这个 while 循环的过程中, 解析 http 请求的 multipart 部分的数据
FileUploadBase. findNextItem
![](https://img-blog.csdn.net/20171202173029057?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTAzOTMzMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
getParsedHeaders, 解析 multipart 元数据信息, 然后 构造FileItemStream返回[带出来一个InputStream, 以及一些需要的元数据]
然后 来到fac.createItem, 这里, 构造DiskFileItem[我们上面碰到的么有生成临时文件的问题, 马上就要出来了],
这里的 item.openStream(), 拿到的是一个 从request.getInputStream() 中那数据, 以boundary结尾作为输入流结束的一个InputStream
-------循环解析 boundary, 给定的文件的数据, 可以参见 FileItemIterator. hasNext, MultipartStream$ItemInputStream
-------解析多个文件之间的分隔符 boundary, 这里是从 content-type 请求头中拿, 参见 FileUploadBase. getBoundary 部分代码
然后 fileItem.getOutputStream(), 拿到的是一个 如果给定的数据小于 sizeThresHold, 就直接存放在ByteArrayOutputStream[服务器内存], 如果超过了 sizeThresHold, 持久化到 repository[临时文件的名字, 可以参见 DiskFileItem. getTempFile]
-------这部分的内容, 可以参见 DiskFileItem. getOutputStream, 以及DeferredFileOutputStream
-------这里的 FileItemFactory. respository的默认值[默认是服务器的临时文件夹], 来自于 CommonsMultipartResolver.setServletContext, mvc的ApplicationContext容器 启动之后, 后置通知过来的
-------DiskFileItemFactory.sizeThresHold 的配置, 可以通过 CommonsMultipartResolver. setMaxInMemorySize 配置
然后 解析玩所有的数据之后, 来到 CommonsMultipartResolver. parseFileItems, 将所有的 "文件" 分类
-------如果是 表单字段, 则获取对应的字符串, 所有的 filedName 相同归于一个字符数组, 需要记录 contentType
-------如果是 文件, 则封装 CommonsMultipartFile
然后 封装 DefaultMultipartHttpServletRequest, 之后返回request, 交给 DispatcherServlet, 走之后的分派逻辑
至此, 这个问题, 差不多 就这样了吧
哦, 对了 因为这个问题, 还抓了一些包, 好久没用过 wireshark 了, 今天 又用了用, 还是有一些收获的, 比如 如何抓本地访问的包
wireshark如何抓取本机包
https://www.cnblogs.com/lvdongjie/p/6110183.html
放一个 "包"
![](https://img-blog.csdn.net/20171202173314624?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTAzOTMzMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
完
参考连接
http://ask.csdn.net/questions/191012 https://www.cnblogs.com/lvdongjie/p/6110183.html
js传递文件到服务器1之后, 通过 HttpClient 的MultipartEntityBuilder, post 服务器1生成的临时文件[file.getFile().getFileItem().getStoreLocation()], 发送到 服务器2, 然后 服务器2接收, 持久化 以及处理响应的业务逻辑
然后 这样的处理方式, 在我自己开发测试的时候, 发现 上传文件是能够上传成功, 然后 之后过了几天, 再来测试, 却发现 上传文件上传不成功了,
然后 查询了一下后面 服务器1的日志, 发现 报的是一个 FNFE, 然后 瞅了一下该临时文件存储的地方, 妈的 居然刚上传的图片没有临时文件生成
然后 网上搜索了一下, 最后 网上搜索了一篇文章, 然后 配置了一下, 临时解决了这个问题, 然后 是准备 周末瞅瞅这块的代码
spring mvc做上传图片,文件小于10k就不生成临时文件了 : http://ask.csdn.net/questions/191012
然后 接下来是正题了, CommonsMultipartResolver 解析请求的流程,
环境 : spring-* : 4.2.5 RELEASE, commons-* : 2.4
FileUploadBase. parseRequest
在这个 while 循环的过程中, 解析 http 请求的 multipart 部分的数据
FileUploadBase. findNextItem
getParsedHeaders, 解析 multipart 元数据信息, 然后 构造FileItemStream返回[带出来一个InputStream, 以及一些需要的元数据]
然后 来到fac.createItem, 这里, 构造DiskFileItem[我们上面碰到的么有生成临时文件的问题, 马上就要出来了],
这里的 item.openStream(), 拿到的是一个 从request.getInputStream() 中那数据, 以boundary结尾作为输入流结束的一个InputStream
-------循环解析 boundary, 给定的文件的数据, 可以参见 FileItemIterator. hasNext, MultipartStream$ItemInputStream
-------解析多个文件之间的分隔符 boundary, 这里是从 content-type 请求头中拿, 参见 FileUploadBase. getBoundary 部分代码
然后 fileItem.getOutputStream(), 拿到的是一个 如果给定的数据小于 sizeThresHold, 就直接存放在ByteArrayOutputStream[服务器内存], 如果超过了 sizeThresHold, 持久化到 repository[临时文件的名字, 可以参见 DiskFileItem. getTempFile]
-------这部分的内容, 可以参见 DiskFileItem. getOutputStream, 以及DeferredFileOutputStream
-------这里的 FileItemFactory. respository的默认值[默认是服务器的临时文件夹], 来自于 CommonsMultipartResolver.setServletContext, mvc的ApplicationContext容器 启动之后, 后置通知过来的
-------DiskFileItemFactory.sizeThresHold 的配置, 可以通过 CommonsMultipartResolver. setMaxInMemorySize 配置
然后 解析玩所有的数据之后, 来到 CommonsMultipartResolver. parseFileItems, 将所有的 "文件" 分类
-------如果是 表单字段, 则获取对应的字符串, 所有的 filedName 相同归于一个字符数组, 需要记录 contentType
-------如果是 文件, 则封装 CommonsMultipartFile
然后 封装 DefaultMultipartHttpServletRequest, 之后返回request, 交给 DispatcherServlet, 走之后的分派逻辑
至此, 这个问题, 差不多 就这样了吧
哦, 对了 因为这个问题, 还抓了一些包, 好久没用过 wireshark 了, 今天 又用了用, 还是有一些收获的, 比如 如何抓本地访问的包
wireshark如何抓取本机包
https://www.cnblogs.com/lvdongjie/p/6110183.html
放一个 "包"
完
参考连接
http://ask.csdn.net/questions/191012 https://www.cnblogs.com/lvdongjie/p/6110183.html
相关文章推荐
- 160920、springmvc上传图片不生成临时文件
- springmvc 上传图片生成临时文件的问题
- spring mvc做上传图片,文件小于10k就不生成临时文件了
- 上传文件细节处理问题(包括中文乱码、限制文件大小、显示上传速度、删除临时文件,随机生成文件夹等)
- thinkphp Upload上传文件在客户端生成的临时文件$_FILES['file']['tmp_name']
- 根据时间随机数生成随机文件名 ,SpringMVC 上传文件
- springmvc上传临时文件目录配置
- thinkphp Upload上传文件在客户端生成的临时文件$_FILES['file']['tmp_name']
- springmvc上传临时文件目录配置
- springMVC_03文件上传 及 临时目录相关
- SpringMVC--上传功能失败,控制台提示找不到文件临时路径(解决办法)
- spring mvc做上传图片,文件小于10k就不生成临时文件了
- spring mvc做上传图片,文件小于10k就不生成临时文件了
- springmvc上传临时文件目录配置
- struts2上传文件不生成临时文件
- jquery.form.js框架实现文件上传功能案例解析(springmvc)
- SpringMVc上传文件
- SpringMVC 实现文件上传和下载
- springmvc 上传/下载 文件
- SpringMVC中的文件上传