`
yanyan_zhl
  • 浏览: 5120 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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文件夹中
分享到:
评论

相关推荐

    非常好的Freemarker中文教程

    Freemarker是一款强大的模板引擎,常...通过详细研读这份教程,开发者不仅可以掌握Freemarker的基本使用,还能深入理解其高级特性和优化技巧,从而在实际工作中更高效地生成静态文件,提升Web应用的性能和用户体验。

    FreeMarker2.3.23官方中文文档

    通过阅读和理解FreeMarker 2.3.23的官方中文文档,开发者能够熟练掌握FreeMarker的使用技巧,从而在Web应用开发中更加高效地创建和管理动态内容。这份文档详尽地涵盖了FreeMarker的各个方面,无论是初学者还是经验...

    FreeMarker+中文手册

    FreeMarker中文手册中会详细解释这些概念和语法,并提供丰富的示例帮助理解和应用。通过深入阅读和实践,你可以掌握FreeMarker的使用,从而更高效地构建动态网页和邮件模板等。同时,理解FreeMarker如何与Spring、...

    FreeMarker中文参考手册以及jar包

    3. **指令**:如`&lt;#include&gt;`用于包含其他模板,`&lt;#import&gt;`引入宏库,`&lt;#function&gt;`定义函数等,它们扩展了FreeMarker的功能。 4. **数据模型**:FreeMarker通过一个称为“Environment”的上下文对象与Java代码...

    freemarker中文学习资料

    这个“freemarker中文学习资料”压缩包提供了详尽的网页版API文档,对于想要深入理解和掌握Freemarker的开发者来说,是一份非常宝贵的资源。 1. **Freemarker基础概念** - **模板语言**:Freemarker使用一种简单的...

    freemarker官方中文帮助文档

    这份“freemarker官方中文帮助文档”提供了详尽的指南,帮助用户深入理解和使用Freemarker。 在《FreeMarker Manual(zh_CN)》中,你可能会了解到以下关键知识点: 1. **基础概念**:Freemarker的核心概念包括...

    freemarker Demo 适用于freemarker初学

    Freemarker是一个强大的模板引擎,常用于JavaEE应用中的视图层处理,尤其与Struts2等MVC框架配合使用,能实现灵活的动态页面...在学习过程中,可以逐步尝试不同的表达式、控制结构和内置功能,加深对Freemarker的理解。

    freemarker 中文手册 (doc)

    通过阅读《freemarker 中文手册》(doc),你可以深入理解上述概念,并学习如何在实际项目中有效地使用Freemarker。手册会详细介绍每个功能的用法,包括示例和注意事项,是学习和查阅Freemarker的宝贵资源。

    freemarker 中文手册

    Freemarker是一个强大的模板引擎,常用于Web应用中的视图层渲染,比如JavaEE的Struts、Spring MVC等框架。它的主要任务是将数据模型与HTML或其他格式的模板结合,生成最终用户可见的动态内容。这个“freemarker 中文...

    转:freemarker中文手册

    对于深入理解Freemarker的工作原理,阅读源码是有帮助的。Freemarker的解析、编译、执行过程涉及多个组件,如`Template`、`TemplateModel`、`TemplateParser`等,它们协同工作以生成最终输出。 总结,Freemarker...

    freeMarker中文手册PDF

    通过阅读这份中文手册,开发者可以掌握FreeMarker的使用方法,理解其核心概念,并学会如何在实际项目中有效利用FreeMarker实现高效、安全的动态页面生成。在Web开发中,熟练运用FreeMarker可以极大地提升开发效率和...

    FreeMarker中文手册+FreeMarkerProgrammerGuide

    "freemarker中文手册"为中文用户提供了方便,它翻译了官方文档的主要内容,使得国内开发者能够更轻松地学习和理解FreeMarker的各项功能。 **8. 学习资源** FreeMarker的官方文档和这两份手册是学习FreeMarker的基础...

    freemarker-2.3.28.jar

    Freemarker是一个强大的模板引擎,主要用于生成动态HTML、XML或其他文本格式的文件,广泛...在"freemarker2.3.28"这个压缩包中,可能包含了Freemarker的完整源代码、文档、示例和其他相关资源,便于深入理解和自定义。

    FREEMARKER中文PDF教材

    2. **数据模型**:理解如何将Java对象映射到Freemarker的数据模型,包括如何设置和访问对象属性,以及使用List、Map等复杂数据结构。 3. **指令**:深入讲解Freemarker的各种指令,如`&lt;#include&gt;`用于导入其他模板...

    FreeMarker手册-Freemarker 2.3.18

    在"FreeMarker手册.pdf"中,你将找到关于这些概念的详细解释、示例代码和最佳实践,对于深入理解和使用FreeMarker是非常有价值的资源。无论你是初学者还是经验丰富的开发者,这本手册都能为你提供必要的指导和支持。

    freemarker-2.3.23-中文手册.zip

    Freemarker是一个强大的、开源的模板引擎,常用于Java Web应用中的视图层技术,它允许开发者使用简单的标记语言(Markup Language)来控制显示逻辑,而无需深入理解HTML或者其他前端技术。这个“freemarker-2.3.23-...

    FreeMarker中文手册

    通过阅读《FreeMarker 2.3.19手册—中文版》PDF,你可以深入理解这个模板引擎的工作原理,学会如何有效地利用它来创建动态页面,提高你的Web开发效率。这份文档详细且全面,是FreeMarker初学者和进阶者不可或缺的...

    SpringBoot中整合freemarker示例代码

    通过这个简单的示例,你应该能理解如何在Spring Boot中有效地使用Freemarker进行模板渲染。这只是一个基础的示例,实际上,Freemarker支持更复杂的逻辑和控制结构,能够满足你在实际开发中的各种需求。

    Freemarker中文手册+教程(史上最全API)

    这个中文手册和教程全面覆盖了Freemarker的各个方面,无论你是初学者还是经验丰富的开发者,都能从中找到所需的知识点,加深对Freemarker的理解,提升开发效率。通过阅读《Freemarker教程_中文版.docx》和...

    freemarker中文PDF文档

    这个“freemarker中文PDF文档”是官方提供的,旨在帮助开发者更好地理解和使用Freemarker。 在PDF文档中,你可能会学到以下关键知识点: 1. **基础概念**: - **模板**:Freemarker的核心,它定义了输出的结构,...

Global site tag (gtag.js) - Google Analytics