彻底解决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方法来获取,只需要知道一种情况就可以了。达到目的才是最重要的,对吧?

有不对之处,欢迎大家进行补充纠错!

时间: 2024-08-29 06:20:34

彻底解决war包中文件路径问题的相关文章

Maven引入本地Jar包并打包进War包中

Maven引入本地Jar包并打包进War包中 1.概述 在平时的开发中,有一些Jar包因为种种原因,在Maven的中央仓库中没有收录,所以就要使用本地引入的方式加入进来. 2. 拷贝至项目根目录 项目根目录即pom.xml文件所在的同级目录,可以在项目根目录下创建文件夹lib,如下图所示:  这4个Jar包是识别网页编码所需的包. 3. 配置pom.xml,依赖本地Jar 配置Jar的dependency,包括groupId,artifactId,version三个属性,同时还要包含scope和

换了应用部署环境,读取jar包中文件遇到的问题。

程序换了个tomcat部署出现了问题,在原来的系统里好好的.最后定位问题发现是使用dom4j读取jar包中文件出现的问题,dom4j的异常是:org.dom4j.DocumentException: null Nested exception: null,经过观察发现拿到的InputStream对象为空.再追代码发现是因为JarFile压根就没有读到文件.顺手换成了当前线程上下文去读取文件,这次抛出的异常很清楚,jar文件找不到.最近经过观察发现是引文文件路径中存在空格,这是和原来系统不同的地方

linux 已安装包校验、rpm包中文件提取

已安装包校验 rpm -V 已安装的包名-V 校验指定rpm包中的文件 rpm -V pth没有任何提示,说明自安装后没有做过任何修改 rpm包中文件提取 比如对一个系统配置文件误操作,可以根据这个文件找到它所属的rpm包,然后再从rpm包中提取这个文件再覆盖被误操作文件 rpm2cpio 包全名 | cpio -idv .rpm包中文件绝对路径-i copy-in模式,还原-d 还原时自动新建目录-v 显示还原过程 rpm2cpio将rpm包转换为cpio格式的文件 cpio是一个标准工具,它

Java中的JAR/EAR/WAR包的文件夹结构说明(转)

JAR包:打成JAR包的代码,一般作为工具类,在项目中,会应用到N多JAR工具包. WAR包:JAVA WEB工程,都是打成WAR包,进行发布,如果我们的服务器选择TOMCAT等轻量级服务器,一般就打出WAR包进行发布. EAR包:这针对企业级项目的,实际上EAR包中包含WAR包和几个企业级项目的配置文件而已,一般服务器选择WebSphere等,都会使用EAR包. 文件夹及作用说明: 1.JAR包 : JAR 文件格式以流行的 ZIP 文件格式为基础. 与 ZIP 文件不同的是,JAR 文件不仅

修改jar包中文件

1.查看jar中文件 jar -tvf abc.jar[待查看的文件 2.解压jar中文件 jar -xvf abc.jar a/b/c[指定待解压的jar中目录,不指定默认解压整个jar包] 3.更新jar中文件 jar -uvf agc.jar a/b/c ·1 文件夹a与agc.jar在同级目录 ·2 不指定文件夹a/b/c,默认当前目录为待更新的目标目录 ·3 覆盖更新指定目录的文件,原jar中不涉及的文件不做修改,亦不删除 例如:更新多个目录文件,(m表示包含MANIFEST.MF文件

nginx中文件路径表示方法

nginx指定文件路径有两种方式root和alias,这两者的用法区别,使用方法总结了下,方便大家在应用过程中,快速响应.root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上. [root]语法:root path默认值:root html配置段:http.server.location.if [alias]语法:alias path配置段:location 实例: location ~ ^/weblogs/ {   

springboot jar启动 读取jar包中相对路径文件报错

jar包启动后读取相对路径文件报异常: Caused by: java.io.FileNotFoundException: class path resource [***.***] cannot be resolved to absolute .***.jar/BOOT-INF/classes!/***.** 采用流的方式读取即可解决 // /template/template.html是resource下面的文件 String template=readfile("/template/tem

解决springboot读取jar包中文件的问题

近期在用springboot封装一些对外服务的API接口,在本机测试都很顺利,可是当我打包jar文件放到服务器上测试的时候发现了类似下面的异常信息: java.nio.file.NoSuchFileException: file:/app.jar!/BOOT-INF/classes!/xxx.properties 于是网上一番搜索,找到类似的解决方法: Properties prop = new Properties();InputStream is = this.getClass().getR

java读取项目中文件路径及乱码解决

this.getClass.getResource(path).getPath(); 如果出现中文乱码,可以使用java.net.URLDecoder.decode方法进行处理 如:URLDecoder.decode(this.getClass.getResource(path).getPath(),"utf-8"); 其他可参考:http://www.cnblogs.com/lostyue/archive/2011/06/27/2091686.html