Java上传下载小结
新到公司,第一个任务是完成公司上传下载组件的开发,之前在学校做过,但有种种问题没有解决,现在回过头来经过努力还是基本完成了功能开发。
普通的上传文件(不使用其他客户端插件),本质上就是把文件通过浏览器处理,作为http请求发向服务器,服务器在收到请求后解析并保存文件到服务器上,通常是直接存储到文件系统中,并在数据库中存储文件的文件信息的过程。
我主要需要解决的问题是在服务器端接收文件,并存储(文件系统、数据库)的过程。
众所周知,文件上传的Form需要设置multipart/form-data,在设置后http请求帧会以不同的方式组织,提交的数据还是作为http体一块提交,但在块中会使用Content-Type中Multipart/form-data后的boundary参数的值来分割,个个表单域,也就是说如果您在一个form里头有x个input,您也想在服务器端获得个个input中提交的值,那您就得获取请求流,并根据boundary对流分段,完成对各个input的值的解析提取。。。好生麻烦。。。so 有人就帮大家做了这些
网上搜了下,流行上传工具包有Apache的Commons-fileupload,SmartUpload,O‘really的cos...SmartUpload比较老就不考虑,网上说cos性能强于Commons-fileupload,所以最终还是使用了cos
COS使用起来很方便,网上也有介绍。。。就是有两套API:MultipartRequest和MultipartPaser,
前者比较简单,可以理解为后者的short-cut方式,通过在构造函数中传入原生request、临时存放路径、最大大小、编码、改名策略,就可以在构造函数执行结束后完成文件上传到指定临时文件夹的任务,之后您可以通过拷贝重命名等完成后续操作
后者是相对底层一点的API,可以分别取得分割后的各个Part,并在之后对Part进行不通操作,我做的就是使用这个相对灵活的API
遇到的问题:
1. 首先还是在一次上传多个文件的情况下,没找打较为合适的方法,告知客户端,Which file is your inputed from that <input>。。。。之前打算用input的name属性来处理,结果失策了,flex组的哥们说没法控制input,flex不和html一样;更失望的是周末回家发现html5 规范里可以在一个input中多选文件上传,结果也就是name是相同的,所以我这个策略是完全的失败
2. 出错回滚,比如您上传5个文件,第二个时候出错了,那前2个怎么处理?这次学到的方法是上传一个往DB里头写一条记录,记录里有状态标识,表示这是零时的,零时的过一段时间会被清理,就不用担心了
3.定时清理线程,可能和正常维护逻辑并发同时操作文件系统和DB,导致竞争条件!我只有把对DB和文件系统的操作在一个service中进行封装,并同步,看似解决了!
4.对于有专门文件Apache Server的情况,直接访问文件而不进过Tomcat更好
5.定时清理线程何时启动,一次启动清理多少文件的力度问题。。。