当前位置: 首页 > 知识库问答 >
问题:

在FreeMarker中检测未定义的变量

颜德馨
2023-03-14

我正在使用FreeMarker构建一个基于模板的代码生成器。由于用户可以用任何语言生成代码,因此在数据模型中提供特定于语言的设置(例如包)是不合适的。但是,如果在FreeMarker模板中定义了它们,则必须定义它们(除非它们是可选的)。

此代码利用FreeMarker抛出的异常查找丢失的值。然后,它用一个临时值填充它们,以便找到其他丢失的值。

源代码fmcodegentest.java:

package codegen;

import freemarker.cache.*;
import freemarker.core.ParseException;
import freemarker.template.*;
import java.io.*;
import java.util.*;

public class FMCodeGenTest {
    private Configuration mConfig = null;
    private HashMap mDataModel = null;
    private Template mTemplate = null;


    public void init() {
        mConfig = new Configuration(Configuration.VERSION_2_3_22);

        try {
            mConfig.setDirectoryForTemplateLoading(new File("./templates"));
            mConfig.setDefaultEncoding("UTF-8");
            mConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        } catch (IOException ie) {
            System.out.println("Error reading templates.");
        }    
    }

    public void buildDataModel() {
        mDataModel = new HashMap();
        mDataModel.put("user", "Foo");

        ArrayList vars = new ArrayList();
        mDataModel.put("vars", vars);

        HashMap var = new HashMap();
        vars.add(var);
        var.put("name", "apple");
        var.put("type", "String");
    }

    public void getTemplate() {
        try {
            mTemplate = mConfig.getTemplate("java_error.ftl");

        } catch (MalformedTemplateNameException ex) {
            System.out.println("Malformed Template Name : " + ex.getMessage());

        } catch (ParseException ex) {
            System.out.println("Parse Error : " + ex.getMessage());

        } catch (IOException ex) {
            System.out.println("IO Exception : " + ex.getMessage());
        }

    }

    public void detectUndefinedVariables() {
        boolean hasBadVars = false;

        do {
            hasBadVars = false;

            try {
                mTemplate.process(mDataModel, new NullWriter());

            } catch (TemplateException ex) {
                hasBadVars = true;

                mDataModel.put(ex.getBlamedExpressionString(), "<temporary value>");

            } catch (IOException ex) {
                System.out.println("IO Exception : " + ex.getMessage());
            }
        } while (hasBadVars);
    }


    public void generateCode() {
        /* Merge data-model with template */
        Writer out = new OutputStreamWriter(System.out);
        try {
            mTemplate.process(mDataModel, out);

        } catch (TemplateException ex) {
            System.out.println("Template Exception : " + ex.getMessage());

        } catch (IOException ex) {
            System.out.println("IO Exception : " + ex.getMessage());
        }
    }

    static public void main(String [] args) {
        FMCodeGenTest test = new FMCodeGenTest();

        test.init();

        test.buildDataModel();

        test.getTemplate();

        test.detectUndefinedVariables();

        test.generateCode();
    }
}

Templatejava_error.ftl:

package ${package};

/**
 *
 * @author ${user}
 */
public class ${name} {
    <#list vars as var>
    private ${var.type} _${var.name};
    nontrivial ${var.notthere};
    </#list>
}

共有1个答案

汪晨
2023-03-14

我认为这不应该通过捕获InvalidReferenceException异常来实现,而是通过使用特殊的数据模型来实现。数据模型本身应该提示丢失的变量。因此,您总是知道用户提供的值应该添加到数据模型的何处,而不需要处理模板本身。

 类似资料:
  • 问题内容: 我想检查变量是否已定义。例如,以下引发未定义的错误 如何捕获此错误? 问题答案: 在JavaScript中,是一个对象。不存在的事物还有另一个价值,。DOM 在几乎所有无法在文档中找到某些结构的情况下都会返回,但是在JavaScript本身中是所使用的值。 第二,不,没有直接对等的内容。如果您确实要专门检查,请执行以下操作: 如果要检查变量是否存在,那只能用/ 来完成,因为它将未声明的

  • 本文向大家介绍如何在JavaScript中检查未定义的变量?,包括了如何在JavaScript中检查未定义的变量?的使用技巧和注意事项,需要的朋友参考一下 要检查变量是否为“未定义”,您需要使用以下命令进行检查。如果结果为“ false”,则表示未定义变量。在这里,变量结果为“ True”- 示例

  • 问题内容: 我们经常在JavaScript代码中使用以下代码模式 有没有更冗长的检查方法具有相同的效果? 根据一些论坛和文献的说法,简单地讲,以下内容应具有相同的效果。 不幸的是,当未定义时,Firebug会将这样的语句评估为运行时错误,而第一个语句就可以了。这仅仅是Firebug的一种(有害的)行为,还是这两种方式之间确实存在某些区别? 问题答案: 您必须区分两种情况: 变量可以是或未 声明的

  • 问题内容: 在jQuery的核心风格指南建议两种不同的方法来检查一个变量是否被定义。 全局变量: 局部变量: 特性: 为什么jQuery为什么对全局变量使用一种方法而对局部变量和属性使用另一种方法? 问题答案: 对于未声明的变量,将返回字符串文字,而身份检查将触发错误 “未定义foo” 。 对于局部变量(您 知道 已在某处声明),不会发生此类错误,因此进行身份检查。

  • 问题内容: 检查JavaScript中的对象属性是否为最佳方法是什么? 问题答案: 检查属性值是否为特殊值的通常方法是: 要检查对象是否实际上没有这样的属性,并因此在尝试访问它时默认情况下将返回: 检查与标识符关联的值是否为特殊值, 或者 尚未声明该标识符。注意:此方法是引用 未声明的标识符(注意:与的值不同)的唯一方法,且不会出现早期错误: 在ECMAScript 5之前的JavaScript版

  • 我在copris v.1.1中使用Akari求解器 这是scalademoapp.scala代码: 尝试执行求解器时会引发此异常: 线程“main”java中出现异常。lang.RuntimeException:目标变量未在jp定义。神户杯。糖解算器。findOptBody(Sugar.scala:631)在jp。神户杯。AbstractSolver$$anonfun$findOpt$1。在jp处