首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Freemarker中import的了解

2012-09-08 
Freemarker中import的理解今天在学习FreeMarker的import的时候突然间出现了一下面这样的错误:Error readin

Freemarker中import的理解
今天在学习FreeMarker的import的时候突然间出现了一下面这样的错误:
Error reading imported file lib/my_test.ftl
The problematic instruction:
----------
==> import '/lib/my_test.ftl' as my [on line 135, column 1 in demo1.ftl]
----------
Java backtrace for programmers:
----------
freemarker.template.TemplateException: Error reading imported file lib/my_test.ftl
at freemarker.core.LibraryLoad.accept(LibraryLoad.java:122)
at freemarker.core.Environment.visit(Environment.java:210)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:210)
at freemarker.core.Environment.process(Environment.java:190)
at freemarker.template.Template.process(Template.java:237)
at com.zhl.freemar.test.TestValue.testFreeMarker(TestValue.java:59)
at com.zhl.freemar.test.TestValue.main(TestValue.java:64)
Caused by: java.io.FileNotFoundException: Template lib/my_test.ftl not found.
at freemarker.template.Configuration.getTemplate(Configuration.java:489)
at freemarker.core.Environment.getTemplateForInclusion(Environment.java:1465)
at freemarker.core.Environment.getTemplateForImporting(Environment.java:1519)
at freemarker.core.LibraryLoad.accept(LibraryLoad.java:112)
... 7 more
开始我很是不解,很像知道FreeMarker在加载导入模板的时候是怎样确定其路径的,根据报错信息翻看了下源码:
下面是LibraryLoad类的构造函数和accept方法的源码

LibraryLoad(Template template,            Expression templateName,            String namespace)    {        this.namespace = namespace;        String templatePath1 = template.getName();        int lastSlash = templatePath1.lastIndexOf('/');        templatePath = lastSlash == -1 ? "" : templatePath1.substring(0, lastSlash + 1);        this.templateName = templateName;    }    void accept(Environment env) throws TemplateException, IOException {        String templateNameString = templateName.getStringValue(env);        if( templateNameString == null ) {            String msg = "Error " + getStartLocation()                        + "The expression " + templateName + " is undefined.";            throw new InvalidReferenceException(msg, env);        }        Template importedTemplate;        try {            if(!env.isClassicCompatible()) {                if (templateNameString.indexOf("://") >0) {                    ;                }                else if(templateNameString.length() > 0 && templateNameString.charAt(0) == '/')  {                    int protIndex = templatePath.indexOf("://");                    if (protIndex >0) {                        templateNameString = templatePath.substring(0, protIndex + 2) + templateNameString;                    } else {                        templateNameString = templateNameString.substring(1);                    }                }                else {                    templateNameString = templatePath + templateNameString;                }            }            importedTemplate = env.getTemplateForImporting(templateNameString);        }        catch (ParseException pe) {            String msg = "Error parsing imported template "                        + templateNameString;            throw new TemplateException(msg, pe, env);        }        catch (IOException ioe) {            String msg = "Error reading imported file "                        + templateNameString;            throw new TemplateException(msg, ioe, env);        }        env.importLib(importedTemplate, namespace);    }

关于模板的加载一定要看几句代码:
LibraryLoad(Template template,            Expression templateName,            String namespace)    {        //获取<#import>所在模板的名称        String templatePath1 = template.getName();        int lastSlash = templatePath1.lastIndexOf('/');        //获取<#import>所在模板的名称的路径        templatePath = lastSlash == -1 ? "" : templatePath1.substring(0, lastSlash + 1);        //<#import >中的表达式,也就是另外一个模板的路径        this.templateName = templateName;    }

然后在看accept中的代码,主要是几个if条件的判断,它们分别代表集中不同了路径的加载方式:
1、
  if (templateNameString.indexOf("://") >0) {  ;  }

  这一种是绝对路径的书写格式,不做任何处理,后面直接执行  
  env.getTemplateForImporting(templateNameString);
2、
 if(templateNameString.length() > 0 && templateNameString.charAt(0) == '/') {     int protIndex = templatePath.indexOf("://");     if (protIndex >0) {         templateNameString = templatePath.substring(0, protIndex + 2) +    templateNameString;     } else {         templateNameString = templateNameString.substring(1);     }  }

  这一种是表达式以"/"开头的情况,表示是加载在该模板下的文件夹中的模板
  如:a.ftl中:<#import "/c/b.ftl" as kk>b.ftl和a.ftl是同级的,都在c文件夹下
3、最后一个else表示通模板在该模板的下一级文件中:
  templateNameString = templatePath + templateNameString;
  如:a.ftl中:<#import "c/b.ftl" as kk>表示c文件夹和a.ftl同级,b.ftl在c文件夹中

热点排行