彻底解决java WEB项目的文件路径问题(war包)
来源:互联网 发布:模考软件 编辑:程序博客网 时间:2024/05/17 08:47
在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方法来获取,只需要知道一种情况就可以了。达到目的才是最重要的,对吧?
有不对之处,欢迎大家进行补充纠错!
update:当使用spring定时器时:request和servletContext就获取不到了,那么要使用这样的办法直接获取ServletContext:
ContextLoader.getCurrentWebApplicationContext().getServletContext()
update20151228:
写文件的时候可能需要获得路径,比如上传文件的时候就需要输出流,而通过ServletContext不能够直接获得输出流的,但可以直接获取实际路径,如:
servletContext.getRealPath("/")
这样获得的路径是${context}/路径,再根据子路径和文件名获取输出流。
- 彻底解决java WEB项目的文件路径问题(war包)
- Java web项目打包成war包的方法
- war包路径问题
- java web项目命令打war包
- 将Java Web项目打成war文件
- 项目打war包遇到的问题
- java web项目的文件路径
- 获得java web项目的文件路径
- Java项目打war包的方法
- Java项目打war包的方法
- Java项目打war包的方法
- Java项目打war包的方法
- Java项目打war包的方法
- linux部署java项目的war包
- Java项目打war包的方法
- 非web工程java项目中的路径问题(针对以jar包运行的工程)
- 通过db.properties文件的存放位置谈java项目及Web项目的路径问题
- 使用MyEclipse14把Java web项目打成war包
- Java重要资源汇总,记录一下。
- xml文件 字符串解析
- ios之开发中常用的设计模式介绍
- Failed to request gap sequence
- QGIS2.6(X64)+ VS2010 + Win8.1 配置与编译
- 彻底解决java WEB项目的文件路径问题(war包)
- 遇到空格,将字符串倒序输出
- SQLite数据库锁问题
- Learing OpenCV cvThreshold
- Delphi自定义类
- 第二天学习
- 排序 快速排序
- 排序算法
- Webstorm & PhpStorm的序列号和证书