Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 4784|回复: 0

彻底解决java WEB项目的文件路径问题(war包)

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-13 15:36:04 | 显示全部楼层 |阅读模式

    在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

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-5 20:56 , Processed in 0.062624 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表