在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. Redis的Docker镜像

    原文地址:https://hub.docker.com/_/redis/ Pull Command docker pull redis Short Description Redis is an op ...

  2. iptalbes -F

    iptalbes -F -F, --flush [chain] Flush the selected chain (all the chains in the table if none is giv ...

  3. typedef那回事儿

    typedef是一种特殊的声明方式,不过它与普通声明(详见这里)的含义取大不相同.普通声明的主角是“变量”,它或是创建一个新变量或是对外文件变量使用前的声明:而typedef声明的主角则是“类型”,通 ...

  4. 分析一帧基于UDP的TFTP协议帧

    下图是UDP的段格式: 相比TCP段格式,UDP要简单得多,也没啥好说的,需要注意的是UDP数据长度指payload加上首部的长度. 下面分析一帧基于UDP的TFTP协议帧: 以太网首部 0000: ...

  5. git配置gitignore

    一.背景                                                                                                 ...

  6. C#预定义类型

    C#提供了16中预定义类型,其中包括13种简单类型和三种非简单类型: 所有预定义类型的名称全部由小写字母组成.预定义的简单类型包括以下3种:11种数值类型.一种Unicode字符类型char.一种布尔 ...

  7. 基于Django的独立运行python脚本开发

    Django框架很方便,比如其方便的ORM,如果写基于Django的独立运行脚本,主要在脚本前面加上以下代码: import sys,os,django sys.path.append(os.path ...

  8. Linux下C++连MySQL数据库

    1.查看本地有没有安装mysql,命令就是mysql,如果有这个命令就表示安装了mysql数据库软件.如果没有就自行安装. MySQL-server-4.0.16-0.i386.rpm MySQL-c ...

  9. Django内置过滤器详解附代码附效果图--附全部内置过滤器帮助文档

    前言 基本环境 Django版本:1.11.8 Python版本:3.6 OS: win10 x64 本文摘要 提供了常用的Django内置过滤器的详细介绍,包括过滤器的功能.语法.代码和效果示例. ...

  10. ny42 一笔画问题

    一笔画问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来. ...