Freemarker:以编程方式读取一些模板参数
Freemarker: read some template parameters programmatically
我正在尝试以编程方式从 Java 中读取一些 freemarker 模板值,如下所示:
public Map<String, Object> getRootAssignments() {
Enumeration en = template.getRootTreeNode().children();
Map<String, Object> map = new HashMap<>();
while (en.hasMoreElements()) {
Object next = en.nextElement();
// instanceof private class does not work
if (next.getClass().getSimpleName().equals("Assignment")) {
map.put(getInternalState(next, "variableName").toString(),
getInternalState(next, "value").toString());
}
}
return map;
}
private Object getInternalState(Object o, String fieldName) {
Field field = null;
boolean wasAccessible = false;
try {
field = o.getClass().getDeclaredField(fieldName);
wasAccessible = field.isAccessible();
field.setAccessible(true);
return field.get(o);
} catch (Exception e) {
return "";
} finally {
if (field != null) {
field.setAccessible(wasAccessible);
}
}
}
有了这个我可以轻松阅读<#assign variable = "value"/>
。但是一旦我需要得到一些需要评估的变量(例如<#assign variable = "first" + "second"/>
),这显然是行不通的。
事实上我不太喜欢这种方法,我更愿意在模板渲染之后读取变量状态,这样就不必再次计算任何内容。可行吗?
如果让 freemarker.core.Environment
保持活动状态,您可以读回变量值,如下所示:
Environment env = myTemplate.createProcessingEnvironment(root, out);
env.process(); // process the template
TemplateModel x = env.getVariable("x");
在您最初的方法中,请注意您使用的 API-s 被标记为内部的,这意味着没有长期的向后兼容性保证。但真正脆弱的是用反思阅读私人领域。然后调用 TemplateObject.getParameterCount
/getParameterRole
/getParameterValue
更稳定,因为那至少是一个 API,即使是内部的。
我正在尝试以编程方式从 Java 中读取一些 freemarker 模板值,如下所示:
public Map<String, Object> getRootAssignments() {
Enumeration en = template.getRootTreeNode().children();
Map<String, Object> map = new HashMap<>();
while (en.hasMoreElements()) {
Object next = en.nextElement();
// instanceof private class does not work
if (next.getClass().getSimpleName().equals("Assignment")) {
map.put(getInternalState(next, "variableName").toString(),
getInternalState(next, "value").toString());
}
}
return map;
}
private Object getInternalState(Object o, String fieldName) {
Field field = null;
boolean wasAccessible = false;
try {
field = o.getClass().getDeclaredField(fieldName);
wasAccessible = field.isAccessible();
field.setAccessible(true);
return field.get(o);
} catch (Exception e) {
return "";
} finally {
if (field != null) {
field.setAccessible(wasAccessible);
}
}
}
有了这个我可以轻松阅读<#assign variable = "value"/>
。但是一旦我需要得到一些需要评估的变量(例如<#assign variable = "first" + "second"/>
),这显然是行不通的。
事实上我不太喜欢这种方法,我更愿意在模板渲染之后读取变量状态,这样就不必再次计算任何内容。可行吗?
如果让 freemarker.core.Environment
保持活动状态,您可以读回变量值,如下所示:
Environment env = myTemplate.createProcessingEnvironment(root, out);
env.process(); // process the template
TemplateModel x = env.getVariable("x");
在您最初的方法中,请注意您使用的 API-s 被标记为内部的,这意味着没有长期的向后兼容性保证。但真正脆弱的是用反思阅读私人领域。然后调用 TemplateObject.getParameterCount
/getParameterRole
/getParameterValue
更稳定,因为那至少是一个 API,即使是内部的。