首页 > 代码库 > 彻底解决war包中文件路径问题
彻底解决war包中文件路径问题
在j2EE项目中,我们一般会把项目打包发布,一般是war包,作为独立单元,可以远程上传,加载,发布,还可以实现版本控制,但这与我们开发过程中使用MyEclipse自动部署有所不同,以下做详细说明.
使用war包部署,在tomcat和WebLogic下部署有很大的区别,tomcat会把war自动加压到当前目录下,然后再用解压的目录来发布,这与一般不会出现太大的意外,但如果是用WebLogic发布,就不会被解压,如果开发过程中不注意,war包发布后就有可能出现找不到文件的现象。例如:使用以下方法获取路径:
this.getClass().getClassLoader().getResource("/").getPath();
这与得到的是绝对Uri路径,例如::/D:/jboss-4.2.2.GA/server/default/deploy/hp.war/WEB-INF/classes/,带盘符的路径,显然在war中无法根据盘符来找到文件
第二种方式:
this.getClass().getResource("/").getPath();
那么这样获取行不行呢?经试验,这与获取的是当前类的Uri目录,例如:/D:/jboss-4.2.2.GA/server/default/deploy/hp.war/WEB-INF/classes/com/jebel/helper/ 也是绝对路径,显然无法适用于war包。
其实以上两种方式都走入了岔路,因为读取文件未必要读取路径,文件操作一般都要转换为流的方式,既然要读取文件,不如直接读成输入流,也少了一步封装。请看以下方式:
InputStream is= this.getClass().getResourceAsStream("/config/bctcms/" + templateFileName);意思是读取classes目录中,目录config/bctcms/下,文件名为templateFileName的文件输入流。经试验在war中可以正常读取到。
该方法存在一个弊端,只能读取classes目录下的文件,对于其他目录下的文件无能为力,显然并不适用于所有场景。
如果文件在WEB-INF目录下,如何进行读取呢?
答案是使用ServletContext.getResourceAsStream(String)方法。也就是先得到上下文信息,然后通过以工程目录为root的绝对路径,找到文件,举例说明:
InputStream is= context.getResourceAsStream(templatePath + "/" + templateFileName); templatePath="/WEB-INF/classes/config/bctcms/" templateFileName="source.xls"可以看到templatePath是相对于context root 的路径,而不是相对于classes,这样即使文件在WEB-INF其他目录下,也可以顺利找到,经测试,对war的情况支持良好。请来看看ServletContext.getResourceAsStream的API文档,
Returns a URL to the resource that is mapped to a specified path. The path must begin with a "/" and is interpreted as relative to the current context root.
This method allows the servlet container to make a resource available to servlets from any source. Resources can be located on a local or remote file system, in a database, or in a .war file.
相信大家都看得懂,就不用赘述了。只是有个问题,context是个什么东西?答案:ServletContext,上下文信息,在j2EE类中使用request获得,如:
ServletContext context = request.getSession().getServletContext();那么在普通类中如何获取呢?暂时特别好的办法,使用application是一种方式,另外一种方式就是想办法先后去request对象,如:
RequestAttributes ra = RequestContextHolder.getRequestAttributes(); HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest(); this.context = request.getSession().getServletContext();这样也是可以获得Context的
但如果是JSP中,可以直接这么获取输入流:
application.getResourceAsStream("xxx”);
路径问题不要纠结太久,根据以上办法解决,最好都用ServletContext方法来获取,只需要知道一种情况就可以了。达到目的才是最重要的,对吧?
有不对之处,欢迎大家进行补充纠错!
彻底解决war包中文件路径问题