当前位置: 首页 > 面试题库 >

如何自检freemarker模板以找出其使用的变量?

李睿
2023-03-14
问题内容

我根本不确定这是否是可以解决的问题,但是假设我有一个freemarker模板,我想问一下该模板使用了哪些变量。

就我的目的而言,我们可以假设freemarker模板非常简单-
只是“根级别”条目(此类模板的模型可以是简单的Map)。换句话说,我不需要处理要求嵌套结构等的模板。


问题答案:

我有相同的任务要从Java端的模板获取变量列表,除了使用反射之外,没有找到任何好的方法。我不确定是否有更好的方法来获取此数据,但这是我的方法:

public Set<String> referenceSet(Template template) throws TemplateModelException {
    Set<String> result = new HashSet<>();
    TemplateElement rootTreeNode = template.getRootTreeNode();
    for (int i = 0; i < rootTreeNode.getChildCount(); i++) {
        TemplateModel templateModel = rootTreeNode.getChildNodes().get(i);
        if (!(templateModel instanceof StringModel)) {
            continue;
        }
        Object wrappedObject = ((StringModel) templateModel).getWrappedObject();
        if (!"DollarVariable".equals(wrappedObject.getClass().getSimpleName())) {
            continue;
        }

        try {
            Object expression = getInternalState(wrappedObject, "expression");
            switch (expression.getClass().getSimpleName()) {
                case "Identifier":
                    result.add(getInternalState(expression, "name").toString());
                    break;
                case "DefaultToExpression":
                    result.add(getInternalState(expression, "lho").toString());
                    break;
                case "BuiltinVariable":
                    break;
                default:
                    throw new IllegalStateException("Unable to introspect variable");
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new TemplateModelException("Unable to reflect template model");
        }
    }
    return result;
}

private Object getInternalState(Object o, String fieldName) throws NoSuchFieldException, IllegalAccessException {
    Field field = o.getClass().getDeclaredField(fieldName);
    boolean wasAccessible = field.isAccessible();
    try {
        field.setAccessible(true);
        return field.get(o);
    } finally {
        field.setAccessible(wasAccessible);
    }
}

我为演示模板自省所做的示例项目可以在github上找到:https
:
//github.com/SimY4/TemplatesPOC.git



 类似资料:
  • 问题内容: 我有一个Freemarker模板,其中包含一堆占位符,在处理模板时会为其提供值。如果要提供userName变量,我想有条件地包括模板的一部分,例如: 但是,FreeMarker手册似乎表明if_exists已过时,但是我找不到其他方法来实现这一目标。当然,我可以简单地提供一个额外的布尔变量isUserName,并像这样使用它: 但是,如果有一种方法可以检查userName是否存在,那么

  • 我正在用Freemarker模板编写应用程序。我通过Java类获得了如何配置和运行. ftl模板机制的知识,并使控制台或文件输出在上面打印模板结果。 但是如何在servlet上实现呢?它是如何工作的?我想跑。类似Tomcat的ftl文件。jsp文件。但它只给我一个错误(“说明请求的资源不可用”)。 有人能给我解释一下怎么跑吗。servlet上的ftl文件? 这是我的web.xml: 这是我的Jav

  • 我使用freemarker为我的xml自定义变量格式化模板,比如_prop.var1。下面是我在map中保存所有道具的上下文并试图使用map格式化变量的数据。 <道具> 提前谢了。

  • 问题内容: 查找在Django模板字典值的常规方法是, 。如果键是循环变量怎么办?即: 失败。如何解决? 问题答案: 编写自定义模板过滤器: (我.get这样使用,如果不存在该键,则不返回任何键。如果执行此操作,则将引发一个then。) 用法:

  • 是否可以访问模板中的设置变量? 设置: 如何使用,而不在模板中重用,以避免重复的代码,尤其是在其层次结构较深的情况下?