设为首页 收藏本站
查看: 453|回复: 0

[经验分享] 相对路径获取Tomcat Web容器中的资源

[复制链接]

尚未签到

发表于 2017-2-6 09:13:48 | 显示全部楼层 |阅读模式
最近做项目碰到个问题,我需要利用velocity模版来渲染一些文本内容出来。也就是用vm来做模版,设置参数,然后我用程序动态产生的参数点进去,最后把渲染好的模版作为String输出。
  项目里面vm模版是一起打包到war包里面的,而我用的是apache的velocity引擎,这个velocity引擎有方法支持vm渲染,但是要给出vm在文件系统中的绝对路径。考虑到灵活性,将模版的绝对路径写到Spring的配置文件(我利用Spring来获取apache的Velocity引擎)中肯定是行不通的。比较理想的方式肯定是制定相对路径,而我这里的这个相对路径就是一个文件夹,所有的模版都放到这个文件夹中。
  在Tomcat的web容器环境中(这里指Selevet这一层,webwork的Action也可以算入这一层),也就是我们在分层结构中通常所说的Web层中是可以通过Servlet的有关API来得到这个模版目录的绝对路径的绝对路径的(应该是通过获取web项目的根路径,然后拼接上相对路径来获得)。但是我的方法并不是在Web层的,让我的类依赖于Web环境来获取这个相对路径,并不是好的设计方法。因此需要有别的方法来获取这个相对路径。
  忙活了一阵子,在不断debug的过程中,终于发现可以用jndi来获得这个绝对路径。把方法保留下来,以备后用。
  在不能使用Servlet API的情况下,可以用Apache的org.apache.naming这个包来获得保存在tomcat运行时环境中的各种资源,这里主要是指目录和文件资源。而这些目录和文件资源都是相对于部署在tomcat中的各个web项目的项目根目录(webroot)的。为了操作jndi资源,我们要做的第一步就是获得jndi上下文,如下:

DirContext dirContext = DirContextURLStreamHandler.get();

在这个dirContext中,通过debug我们可以看到里面放了除了类路径下之外的所有资源,当然是相对于webroot的。现在假设我们的模版放在/webroot/templates下面。下面的代码就可以获得模版目录的绝对路径:

//获得上下文
DirContext dirContext = DirContextURLStreamHandler.get();
//查询templates这个目录资源
Object obj = dirContext.lookup("/templates");
FileDirContext fdc;
String webrootPath;
// 判断取出来的对象是不是FileDirContext
// 也就是判断这个资源名对应的资源是不是目录资源
if (obj instanceof FileDirContext) {
fdc = (FileDirContext) obj;
// 获取web项目根目录的绝对路径
webrootPath = fdc.getDocBase();
}
String templatesPath = webrootPath + "/tempaltes";

  上面的代码先获得目录上下文,然后获得目录资源。这里判断了一下获得Object是不是FileDirContext,在jndi中,所有的目录资源都被抽象成FileDirContext这个对象。如果是文件就会被抽象成FileDirContext.FileResource这个对象。
  如果不是目录资源,比如是一个文件资源,那返回的ProxyDirContext这个对象,获得文件资源的方法在后面讲。
  但是,看apache的api,会发现你是没有办法拿到FileResource这个对象,因为目前的api没有暴露出来。虽然在debug的时候会发现,FileDirContext里面已经有属性(具体那个属性忘了)保存着我想要的东西了,但是就是没有办法通过api来得到这个东西。着实郁闷了一把。
  我尝试了各种方法,看了几遍api,都没有找到能够从FileDirContext里面直接获取我想要的属性的方法(也就是templates目录的绝对路径)。最后发现FileDirContext有个getDocBase()方法,能够拿到web项目的根目录的绝对路径。
  后来我想了一下,其实拿到这个根目录的绝对路径基本也就足够了,因为我们在web项目中指定资源的相对路径时,通常都是从webroot开始的。估计也是因为这个,大家在制定相对路径时都从webroot开始制定。
  拿到webroot之后,就可以拼接上我的模板目录的相对路径,然后获得模板目录的绝对路径了。为了方便,可以把这个相对路径做成Bean的一个属性,然后在Spring的配置文件中设定。如果想更方便,那就用maven。在一个外部文件中设定这个值。
  下面来说说获取文件资源,获取文件资源的思路基本相同,只不过换了另外一个类而已。如果是文件资源可以用下面的代码:

//获得上下文
DirContext dirContext = DirContextURLStreamHandler.get();
//查询templates这个目录资源
Object obj = dirContext.lookup("/templates/test.vm");
FileDirContext fdc;
String webrootPath;
// 判断取出来的对象是不是FileDirContext
// 也就是判断这个资源名对应的资源是不是目录资源
if (obj instanceof ProxyDirContext) {
fdc = (FileDirContext) obj;
// 获取web项目根目录的绝对路径
webrootPath = fdc.getDocBase();
}
String templatesPath = webrootPath + "/tempaltes/test.vm";

  区别就在红色标注的9,15两行代码,lookup返回的类不一样了,变成ProxyDirContext了。ProxyDirContext中也有一个getDocBase方法,通过它拿到web项目的绝对路径,然后拼接上文件资源的相对路径也就拿到了完整的路径。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-338067-1-1.html 上篇帖子: 用ANT打包Struts2项目并发布到tomcat里 下篇帖子: 从tomcat 迁移到 WebSphere 经验总结(修改)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

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