我试图从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"/>
),这显然不起作用。
实际上我并不喜欢这种方法,我宁愿在模板渲染后读取变量状态,因此不需要再次评估任何内容。这可行吗?
答案 0 :(得分:1)
如果让freemarker.core.Environment
保持活着,你可以读回变量值,如下所示:
Environment env = myTemplate.createProcessingEnvironment(root, out);
env.process(); // process the template
TemplateModel x = env.getVariable("x");
从最初的方法开始,请注意您使用的是标记为内部的API,这意味着没有长期向后兼容性保证。但真正脆弱的是用反思阅读私人领域。然后调用TemplateObject.getParameterCount
/ getParameterRole
/ getParameterValue
会更稳定,因为它至少是一个API,即使是内部的。