java web应用程序中代码与数据的分离方案(转)

       经常开发java web应用程序的朋友一定对有对程序打包,维护的经验,我们提高软件的维护性一般可以从分离易变和不变的内容,重构软件的结构来实现,重构包括对代码级别的,也包括对应用程序目录文件的重构,以下我就简单谈谈我的一次经历。


       我们一个系统是java web应用程序,不过该系统所有的class文件、jsp、js、css、image文件和系统动态上传的doc、xls、image、wmv等文件放在同一个工程目录中。具体目录结构如下:

应用程序配置的上下文根目录是/myapp
myapp/WEB-INF/
myapp/admin/
myapp/images/
myapp/style/
myapp/files/
myapp/videos/
......

 

 

    1、存在的问题
       实际上,files、videos文件夹,会在系统运行中随着用户上传发布新内容经常更新变化,而其他的部分都是在系统需求变更发布版本时才变化,这2种变化不同,前者是系统正常使用的结果,后者是系统变更的结果,根据变化与不变化分开的原则,我们希望把这2类文件夹分开存放。
       由于我们发布web应用程序包(myapp.war)需要把应用程序上下文根目录myapp中的所有文件夹都包括进来,所以必须把经常变化的files和videos文件夹移出去。

 

 

    2、解决方法探索
       我们知道,servlet中有两种转向的方法,一个是request.getRequestDispatcher(requestPath).forward(request,

response),它不改变url地址,直接转发请求到一个jsp页面,一个是resonse.sendRedirect(urlPath),它改版url地址,跳转到另外一个请求。 不过其两者都没法访问servlet所在web应用程序上下文(myapp)之外的目录,而我们myapp内的全部文件夹都需要打包成myapp.war,这样就有个矛盾。
       另外的方法,还有通过java.io.File使用流的方式读一个文件,然后再使用servlet的response的out对象写出来传送到页面,这样的方法可以访问到该web容器(如tomcat)所在操作系统的用户根目录(如windows的D:/或linux的/usr*等等),这样我们就可以把files等文件夹移动到myapp之外。比如tomcat的应用程序上下文根目录是/usr/tomcat/webapps/,我们让files不在myapp中,而是放到/usr/upload/files中,这样我们打包myapp.war的时候,就只装载版本变化的最新版程序,用户上传文件都不变仍然放在files中,访问时使用File()来进行。如:
       File f = new File("/usr/upload/files/2010/3/15/010001.doc")

使用FileInputStream来读这个文件,然后使用response中的outstream来写这个文件流到页面。
       这其中存在的问题是读入的文件需要占用JVM的heap空间,如果文件有500MB大,那么一般的默认JVM heap空间都是不够的,需要在启动JVM的时候设置参数,使之足够容纳这个文件,当然文件的读写都要使用JVM来调度,显然效率会比较低,比直接读取要慢很多。

 

 

    3、方法的改进
       有没有办法,既能让files文件夹在myapp之外,又不用File类来读文件数据流呢? 在linux中可以使用目录的快捷方式来解决,实际上就是文件的软连接功能。
       大家都知道,在linux中文件和文件夹是同样的数据实体,可以用同样的方法来做连接,在另外一个地方操作某个文件或目录的连接,就达到了直接操作这个文件或目录的作用。
       首先,建立软连接的方式是:
       ln -s sourcePath destinationPath
把files文件夹放在myapp之外,并且在webapps中的某一个应用程序中,比如ROOT中建立一个files文件夹的软连接,如:
       ln -s /usr/upload /usr/tomcat/webapps/ROOT/upload
并且在ROOT的tomcat容器context中设定一个属性 allowLinking="true" ,即可访问
       这样,我们可以在myapp应用程序中,通过直接url调用,或者response的重定向方式,访问到files中的文件,如:
       http://localhost:8080/upload/files/2010/3/15/010001.doc
       这样一来,访问upload快捷方式就等于是访问了upload文件夹,既没有访问外在资源没有权限限制,又没有使用File类读写数据流,不会有heap空间的限制,我们实现了易变数据文件的分离,并且没有内存的消耗。读写500MB的文件,不需要把heap空间设置到500以上,只需要默认的64就可以了。
       总结一下,利用操作系统的特性——软连接,实现了数据文件从应用程序包中的分离,操作系统实现目录文件访问的跳转,利用了文件I节点的修改,这属于操作系统底层实现,比起利用JVM的应用层类File来实现读写要快10倍以上,节约JVM Runtime空间。

 

 

    4、总结
       我为了让web应用程序易于维护,把版本发布的程序代码和用户上传的数据文件分离,经过了对servlet重定向方法的思考和试验,对File类文件流方法的试验,对linux文件软连接的方法试验,最好决定使用最后一种,同时解决了文件维护性和运行效率的问题。

 

 

转载于:https://www.cnblogs.com/weijunqiang/articles/2495599.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值