问题描述
根据教程学习Freemarker过程中发现一直报错,报错内容是<#list noteList as note>中无法获得${note.title}值
严重: Error executing FreeMarker template
FreeMarker template error:
The following has evaluated to null or missing:
==> note.title [in template "demo.ftl" at line 8, column 15]
发现debug信息以后,直接在markdown.flt
中输出${note}进行查看,发现整个对象都是有值得,能输出Note{title='测试', comment='no', code='note', fromFileName='23', fromFileType='re'}
。在网上搜索后,回答都没有解决问题。后来继续搜索了最新的教程后发现都没有这个问题,觉得还是自己的代码有问题。
解决方法
最终,在经过努力后,发现问题主要是Freemarker有些默认的设置得遵从,规则如下:
💡注意点:
model中存放的map的key只能是string
-
给模板提供的List,存放的对象如果是POJO,则必须
- 必须是
public
类,即不能跟运行Java程序类放在一起; - 取值通过的是类对象属性的
getter
方法,属性是public的也不行==>必须实现类属性的getter方法
▲即遵从JavaBean规范
- 必须是
输出结果
完整的工程代码如下
- 运行的java源码
public class FreeMakerTest {
public static void main(String[] args) throws IOException, TemplateException {
Configuration configuration = new Configuration(Configuration.getVersion());
configuration.setDirectoryForTemplateLoading(new File(new ClassPathResource("template").getURI()));
// 设置输出文档
File outputFile = new File("output.md");
BufferedWriter writer = IOUtils.buffer(new OutputStreamWriter(new FileOutputStream(outputFile)));
// 设置模板数据
Map<String, Object> model = new HashMap<>();
model.put("topic", "read");
ArrayList<Note> noteList = new ArrayList<>();
noteList.add(new Note("测试", "no", "note", "23", "re"));
model.put("noteList", noteList);
// 输出结果
Template template = configuration.getTemplate("markdown.ftl");
template.process(model, writer);
// 关闭流
writer.close();
}
}
-
template/markdown.ftl
内容
# ${topic}
[TOC]
<#list noteList as note>
## ${note.meTitle}
### ${note.fromFileName}
${note.comment}
```${note.fromFileType}
${note.code}
```
</#list>
- POJO对象
package test.freemakers;
/**
* @author MrLi
* @date 2022-11-20 15:19
**/
public class Note {
public String m_title;
private String comment;
private String code;
private String fromFileName;
private String fromFileType;
public Note(String title, String comment, String code, String fromFileName, String fromFileType) {
this.m_title = title;
this.comment = comment;
this.code = code;
this.fromFileName = fromFileName;
this.fromFileType = fromFileType;
}
@Override
public String toString() {
return "Note{" +
"title='" + m_title + '\'' +
", comment='" + comment + '\'' +
", code='" + code + '\'' +
", fromFileName='" + fromFileName + '\'' +
", fromFileType='" + fromFileType + '\'' +
'}';
}
public String getMeTitle() {
return m_title;
}
public String getComment() {
return comment;
}
public String getCode() {
return code;
}
public String getFromFileName() {
return fromFileName;
}
public String getFromFileType() {
return fromFileType;
}
}