在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)方法。

也就是先得到上下文信息,然后通过以project文件夹为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}/路径,再依据子路径和文件名称获取输出流。

来源:https://www.cnblogs.com/zhchoutai/p/7124409.html

彻底解决java WEB项目的文件路径问题(war包)的更多相关文章

  1. (转)Java web 项目中文件路径

    文件路径分为绝对路径和相对路径,在项目中页面跳转.配置文件读写.文件上传下载等等许多地方都涉及到文件路径问题. 一篇好文转载于此:http://blog.csdn.net/shendl/archive ...

  2. JAVA WEB项目中各种路径的获取

    JAVA WEB项目中各种路径的获取 标签: java webpath文件路径 2014-02-14 15:04 1746人阅读 评论(0) 收藏 举报  分类: JAVA开发(41)  1.可以在s ...

  3. java web项目获取各种路径

    1.可以在servlet的init方法里 String path = getServletContext().getRealPath("/"); 这将获取web项目的全路径 例如 ...

  4. linux 下用renameTo方法修改java web项目中文件夹名称问题

    经测试,在Linux环境中安装tomcat,然后启动其中的项目,在项目中使用java.io.File.renameTo(File dest)方法可行. 之前在本地运行代码可以修改,然后传到Linux服 ...

  5. 读取web项目properties文件路径 解决tomcat服务器找不到properties路径问题

    1.需求:有时候我们产品经理给我们的需求是会不断变化的,例如数量是1000现在变成500,我们不可以去改代码吧,这样很麻烦,所以就可以改配置文件properties(这个数据库链接一样),当然也有js ...

  6. Java web 项目的相对路径的使用

    在java Web中有些地方读取文件需要相对路径.在Java Web 中如何使用相对路径呢? Java Web 在发布项目的时候. 发布根路径下WEB-INF/classes 默认使用该方法的路径是: ...

  7. 理解java Web项目中的路径问题

    本文以项目部署在tomcat服务器为例,其他相信也是一样的. 先说明请求页面的写法,在web中,页面路径主要写的有以下几种 1.请求重定向 2.浏览器的请求被服务器请求到新页面(我称为“转发”) 3. ...

  8. Java Web 项目的文件/文件夹上传下载

    需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验: 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包 ...

  9. 解决java web项目导入后出现的问题 ---cannot be read or is not a valid ZIP file

    导入以前的web项目后会出现以下三个错误: 1. Archive for required library: ‘WebContent/WEB-INF/lib/readme.txt’ in projec ...

随机推荐

  1. PLSQL_Oracle基本概念总结(汇总)

    2014-08-16 Created By BaoXinjian

  2. python标准库介绍——10 sys 模块详解

    ==sys 模块== ``sys`` 模块提供了许多函数和变量来处理 Python 运行时环境的不同部分. === 处理命令行参数=== 在解释器启动后, ``argv`` 列表包含了传递给脚本的所有 ...

  3. 「Java Web」主页静态化的实现

    一个站点的主页一般不会频繁变动,而大多数用户在訪问站点时不过浏览一下主页(未登陆).然后就离开了.对于这类訪问请求.假设每次都要通过查询数据库来显示主页的话,显然会给server带来多余的压力. 这时 ...

  4. 【Android】9.3 自定义列表视图的外观

    分类:C#.Android.VS2015: 创建日期:2016-02-18 一.简介 自定义的列表视图通常用Resources/Layout文件夹下的axml文件中的资源来声明,适配器则通过Id去加载 ...

  5. LeetCode242——Valid Anagram

    Given two strings s and t, write a function to determine if t is an anagram of s. For example, s = & ...

  6. 深入了解MySQL的索引

    (一)关于存储引擎   创建合适的索引是SQL性能调优中最重要的技术之一.在学习创建索引之前,要先了解MySql的架构细节,包括在硬盘上面如何组织的,索引和内存用法和操作方式,以及存储引擎的差异如何影 ...

  7. 新手MySQL工程师必备命令速查手册

    MySQL的基本操作可以包括两个方面:MySQL常用语句如高频率使用的增删改查(CRUD)语句和MySQL高级功能,如存储过程.触发器.事务处理等.而这两个方面又可以细分如下: 1.MySQL常用语句 ...

  8. Java多线程面试大全

    什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位,可以使用多线程对进行运算提速. 比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务 ...

  9. boost.asio源码剖析(三) ---- 流程分析

    * 常见流程分析之一(Tcp异步连接) 我们用一个简单的demo分析Tcp异步连接的流程: #include <iostream> #include <boost/asio.hpp& ...

  10. android studio 报Error:failed to find Build Tools revision 23.0.0 rc2

    每个项目的build.gradle里可以设置,例如 android { .... buildToolsVersion '23.0.0 rc2' .... } 1 2 3 4 5 如下图,我的Andro ...