项目现状: 两台服务器通过nfs共享public目录, public 目录存js,css ,图片等文件,这部分文件经常有增加,更新的需求,偶尔有删除的需求,其实并没有执行过删除操作,不想更新部分文件时,就会将整个public更新到服务器上去,虽然花费时间长,但是十分省事。 用户上传的文件存储在public/upload 目录下, 通过 aaa.com/public/ 来访问项目的静态资源。
关于 upload 目录的一些限制,
1: 有时我想删除整个public,然后重新上传,但是由于upload的存在,不管public存在多少多余的文件,我都不敢删除public。
2: 上传整个public目录时,总担心 upload 目录的文件被本地测试文件替换,虽然本地upload和线上upload 存在同名文件的概率很小。(注:最好不要从本地上传文件至服务器,之前在红麦的做法一直都是从svn上更新代码)
3: 关于把项目名称改改,部署到另外一个目录,或者新增一个实例的想法都不敢有,操作起来太麻烦。如果是使用tomcat来进行部署更是一种灾难。
/opt/xfyh/apache-tomcat-7.0.94/webapps/ROOT/WEB-INF/application/public/upload。 虽然我知道你可能会说 tomcat 和 war 分离
<Context path="" docBase="/usr/local/tomcat-f/war/app.war"></Context> ,但是前面两个问题还是会存在。
4:打成jar包,使用java -jar 来运行,几乎没有这个可能。
因此将项目文件和用户上传文件分离开还是十分必要的。 解决办法也无非就是将upload 目录移到项目外面去, 具体做法如下:
1: 配置 routes 文件
将所有的 /upload/xxx 请求mapping 到 UploadController.index 上面去。
2: UploadController.index 处理逻辑如下,主要在于找到文件的绝对路径。
3: 上传文件时的处理: 将tmp目录的文件 copy 到 uploadPath 目录中去即可。
相应的spring的解决方案:
相比较而言 spirng 的解决方案更加灵活,因为spring的解决方案能添加任意多个静态资源目录。
关于其他play的不足之处:
1:需要程序员手动的删除文件, 而tomcat 的 DiskFileItem 类通过析构函数来清除文件 。
2:没法限制表单中文件的数量和大小,你可以一个表单提交 10个10G的文件,play对此没用任何感觉。 流量攻击,不存在。
而tomcat 能限制单个请求的大小,以及单个文件的大小。
删除文件不可怕,可怕的是删除整个tmp目录 , 更可怕的这个错误并不会触发,因为根本不存在同时并发上传文件的时候。
3 :Play 自己实现了一套模板引擎,刚开始觉得这套模板很厉害,很实用(相对于jstl而言),但是用过 thymeleaf 模板引擎后我倒是喜欢上了后者。
当然如果有文件服务,将图片上传至文件服务器将会是更好的选择,
1: 不用自己来保障图片的安全性,备份,扩容,容灾啥的都不用自己操心
2:一般的文件服务器都会使用cdn进行加速,全国各地访问文件的速度一样快。
3: 加快网页的呈现速度,一般的文件服务会有至少一个单独域名。
不过该点赞的还是得点赞 , 它有防脚本攻击。