最近寫freemarker項目的時候遇到一個錯The following has evaluated to null or missing,改了一上午才改好,特意寫下,以此爲鑑!
Music 實體類(問題就出在這!!!!!!!!)
import java.io.Serializable;
public class Music implements Serializable{
private String M_Name; //歌名
private String M_Singer; //歌手
private String M_Time; //時長
private String M_Publish_Time; //發佈時間
private String M_Album; //專輯
public Music() {
super();
}
public Music(String mName, String mSinger, String mTime,
String mPublishTime, String mAlbum) {
super();
M_Name = mName;
M_Singer = mSinger;
M_Time = mTime;
M_Publish_Time = mPublishTime;
M_Album = mAlbum;
}
//get、set方法略
}
ftl模板
${music.M_Name}
${music.M_Singer}
${music.M_Time}
${music.M_Publish_Time}
${music.M_Album}
測試類:
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class FreeMarkerTest {
public static void main(String[] args) throws Exception {
String dir="C:\\Users\\xyk\\Workspaces\\MyEclipse 8.6\\StaticHtml\\WebRoot\\WEB-INF\\templates";
Configuration conf = new Configuration();
//加載模板文件(模板的路徑)在此用的是磁盤下的具體路徑
conf.setDirectoryForTemplateLoading(new File(dir));
// 加載模板
Template template = conf.getTemplate("/test.ftl");
// 定義數據
//多個個數據
/*Map root = new HashMap();
root.put("a", 123);
root.put("b", 456); */
//單個對象
Map <String,Object> root = new HashMap<String,Object>();;
Music music=new Music("陰天","莫文蔚","3:54","2013.10.23","莫後年代 莫文蔚20週年世紀典藏 (The Age of Moknificence)");
root.put("music", music);
// 定義輸出
Writer out = new FileWriter(dir + "/test.html");
template.process(root, out);
System.out.println("轉換成功");
out.flush();
out.close();
}
}
報錯:
嚴重: Error executing FreeMarker template
FreeMarker template error:
The following has evaluated to null or missing:
==> music.M_Name [in template "test.ftl" at line 1, column 3]
----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to be legally refer to something that's null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: ${music.M_Name} [in template "test.ftl" at line 1, column 1]
----
Java stack trace (for programmers):
----
freemarker.core.InvalidReferenceException: [... Exception message was already printed; see it above ...]
at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:108)
at freemarker.core.EvalUtil.coerceModelToString(EvalUtil.java:346)
at freemarker.core.Expression.evalAndCoerceToString(Expression.java:80)
at freemarker.core.DollarVariable.accept(DollarVariable.java:40)
at freemarker.core.Environment.visit(Environment.java:257)
at freemarker.core.MixedContent.accept(MixedContent.java:57)
at freemarker.core.Environment.visit(Environment.java:257)
at freemarker.core.Environment.process(Environment.java:235)
at freemarker.template.Template.process(Template.java:262)
at Test.FreeMarkerTest.main(FreeMarkerTest.java:40)
Exception in thread "main" FreeMarker template error:
The following has evaluated to null or missing:
==> music.M_Name [in template "test.ftl" at line 1, column 3]
----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to be legally refer to something that's null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: ${music.M_Name} [in template "test.ftl" at line 1, column 1]
----
Java stack trace (for programmers):
----
freemarker.core.InvalidReferenceException: [... Exception message was already printed; see it above ...]
at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:108)
at freemarker.core.EvalUtil.coerceModelToString(EvalUtil.java:346)
at freemarker.core.Expression.evalAndCoerceToString(Expression.java:80)
at freemarker.core.DollarVariable.accept(DollarVariable.java:40)
at freemarker.core.Environment.visit(Environment.java:257)
at freemarker.core.MixedContent.accept(MixedContent.java:57)
at freemarker.core.Environment.visit(Environment.java:257)
at freemarker.core.Environment.process(Environment.java:235)
at freemarker.template.Template.process(Template.java:262)
at Test.FreeMarkerTest.main(FreeMarkerTest.java:40)
注意:其實錯誤原因就是實體類的屬性命名不規範
private String M_Name; //歌名
private String M_Singer; //歌手
private String M_Time; //時長
private String M_Publish_Time; //發佈時間
private String M_Album; //專輯
屬性名字不符合javabean的規範!也就改 實體類 和 flt模板 ,把首字母改爲小寫!M–>m
改完後代碼:
import java.io.Serializable;
public class Music implements Serializable{
private String m_Name; //歌名
private String m_Singer; //歌手
private String m_Time; //時長
private String m_Publish_Time; //發佈時間
private String m_Album; //專輯
public Music() {
super();
}
public Music(String mName, String mSinger, String mTime,
String mPublishTime, String mAlbum) {
super();
m_Name = mName;
m_Singer = mSinger;
m_Time = mTime;
m_Publish_Time = mPublishTime;
m_Album = mAlbum;
}
//get、set方法略
}
ftl改後:
${music.m_Name}
${music.m_Singer}
${music.m_Time}
${music.m_Publish_Time}
${music.m_Album}
生成的html文件: