作者:张明星 2006.04.12. MSN:
fastzch(at)hotmail.com题外话:感谢开源精神,如果不是她,我今天可能就不会如此顺利的找到解决问题的方法。
Velocity主要是一个在MVC框架中解决View层问题的框架,其模版功能十分之强大,可以用来做很多事情,据传曾有人用这个来生成程序,还有生成JSP文件等,不过后来也发现这样做的维护开销极大,而且毕竟没有人那多智能。但是在View层做一些改进还是很好的,虽然我并没有拿她来做这样的事,但是从我用她来实现其它的功能便可感受到。
我见过的使用Velocity较好的项目有DLOG4J(中文官方网站为:
http://www.javayou.com/main.jspe?cat_id=7),天乙BBS(
http://www.laoer.com/)等,大家有兴趣的话可以去看看。
我用Velocity主要是在项目中做为生成各类系统MAIL的template,所以在使用的时候虽然是在WEB应用中,但是并不是做为View层的模版,也不用在web.xml文件中加一堆配置,但是问题随之也产生了。
Velocity读取模版文件的方式采用的是File类,每次都会自动将我们给出的模版的相对路径解析成一个绝对路径,然后再用File类读入,这如果对于一个本地运行的Application来说不会有太大的问题(存在的问题就是模版文件不能一起打包在.JAR文件中,只能放在JAR包的外面,具体位置为与JAR包同一目录下)。这样的方式,对于WEB应用中的相当于资源文件的方式来说简直就是一种灾难,无论是将这些文件放在classes目录下,还是放在lib目录下,都会找不到资源文件。
无奈之下,我只好跟进Velocity的源码,一看究竟。经过一翻追踪,发现模版文件的加载主要由FileResourceLoader这个类来搞定,而且加载模版文件的实现十分繁杂(主要是方法间的调用让人看得极为眼花),最终使用的方法如下:
1 private InputStream findTemplate(String path, String template)
2 {
3 try
4 {
5 File file = new File( path, template );
6 if ( file.canRead() )
7 {
8 return new BufferedInputStream(
9 new FileInputStream(file.getAbsolutePath()));
10 }
11 else
12 {
13 return null;
14 }
15 }
16 catch( FileNotFoundException fnfe )
17 {
18 /*
19 * log and convert to a general Velocity ResourceNotFoundException
20 */
21 return null;
22 }
23 }
在这段code中,关键所在即为 File file
= new File( path, template ),所以如果在web应用中运行的话,非把文件放到运行时系统所处的相对路径下才能成功,这对于WEB的部署带来的也是灾难性的后果。
我曾试着在上面这段code的第5行下面用file.getAbsolutePath()得到其绝对路径,作为Application运行的时候,得到的是项目所在的工作目录,而我在Web应用环境下得到的结果却让我大吃一惊,结果居然是:c:\windows\system32(我采用的平台是WinXP+Tomcat5.0.28)。各位看官,到此是不是令你咋舌了?你一定也会觉得这有些不可思议,这样的结果弄得跟系统都变得相关了。
经过一番分析发现有一个极其简单的解决办法(或许我总是喜欢用简单的办法解决问题,这可能也是受XP的影响),将上面的代码改为如下:
1 private InputStream findTemplate(String path, String template)
2 {
3 try
4 {
5 File file = new File( path, template );
6
7 // System.out.println(file.getAbsolutePath());//for test
8 // System.out.println(template);
9 if ( file.canRead() )
10 {
11 return new BufferedInputStream(
12 new FileInputStream(file.getAbsolutePath()));
13 }
14 else
15 {
16 // return null;//before modified.
17
18 return this.getClass().getClassLoader().getResourceAsStream(template);
19 }
20 }
21 catch( FileNotFoundException fnfe )
22 {
23 /*
24 * log and convert to a general Velocity ResourceNotFoundException
25 */
26 return null;
27 }
28 }
看看,是不是超级简单。
Compile,打包,搞定!
经过测试,现在无论是将模版文件一起打包到JAR包中还是放到Classes目录下均可。
PS:将模版文件用作View层的Web应用没有测试过,有兴趣的朋友可以帮我测一把。谢谢! 如有错误,欢迎指正。
posted on 2006-04-12 19:54
Robin's Programming World 阅读(3147)
评论(5) 编辑 收藏 所属分类:
Java