zoukankan      html  css  js  c++  java
  • 彻底解决java WEB项目的文件路径问题(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)方法。

    也就是先得到上下文信息,然后通过以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

  • 相关阅读:
    Linux Centos7配置mysql8.0数据库
    Linux Centos7配置ftp服务器
    线程池工具ThreadPoolExecutor
    Layui 实现input 输入和选择
    canvas验证码实现
    弹性布局flex 介绍
    java EE 新手入门了解
    java web工程web.xml介绍
    js 数组常用的一些方法
    详解为什么需要重写hashcode 和 equals 方法
  • 原文地址:https://www.cnblogs.com/kongxc/p/8527446.html
Copyright © 2011-2022 走看看