您的位置:首页 > 编程语言 > Java开发

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



在这个 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: