日期:2014-05-16 浏览次数:20454 次
Freemarker中取Session中对象出现Expression Session is undefined异常,
还有在模板中无法使用jsp标签,出现Expression JspTaglibs is undefined异常。
其实两个原因是相同的,都是在ftl模板中没有找到对应的对象Session或 JspTaglibs ,通常我们使用freemarker有三种手段。
其一,是通过使用freemarker.ext.servlet.FreemarkerServlet。在web.xml中配置freemarkerServlet就可以通过*.ftl直接访问指定路径的freemarker模板,并生成对应的文件/流进行输出。我认为这种方式最简便的一种,然而其中生成的文件被限定为html或xml文件,编码之类都被统一处理,对于不同输出要进行多次配置。
第二种方式是使用页面框架,这些页面框架都是调用freemarker配置使用模板进行输出,最大好处是与现有框架集成,可以使用页面框架的一些特性,并且可以进行一定程序定制,如指定文件类型和编码等。
第三种方式是手动进行封装,直接调用配置使用模板生成指定的内容。其有个好处,是可以进行定制,如文件类型和编码都可以进行指定的配置,并且更多人是使用模板生成指定文件进行页面静态化,程序员通过将后台信息使用freemarker生成静态文件,再由用户进行调用。
通常前两种方式对一些数据对象封装使得使用模板时能进行调用,可以满足用户需求。而开始列出的两个错误通常出现在手工进行封装的时候。举代码为例:
Java代码
1.public static void crateHTML(ServletContext context,Map<String,Object> data,String templatePath,String targetHtmlPath){ 
2. Configuration freemarkerCfg = new Configuration(); 
3. //加载模版 
4. freemarkerCfg.setServletContextForTemplateLoading(context, "/"); 
5. freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8"); 
6. try { 
7. //指定模版路径 
8. Template template = freemarkerCfg.getTemplate(templatePath,"UTF-8"); 
9. template.setEncoding("UTF-8"); 
10. //静态页面路径 
11. String htmlPath = context.getRealPath("/html")+"/"+targetHtmlPath; 
12. File htmlFile = new File(htmlPath); 
13. Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8")); 
14. //处理模版 
15. template.process(data, out); 
16. out.flush(); 
17. out.close(); 
18. } catch (Exception e) { 
19. e.printStackTrace(); 
20. } 
21.} 
public static void crateHTML(ServletContext context,Map<String,Object> data,String templatePath,String targetHtmlPath){
Configuration freemarkerCfg = new Configuration();
//加载模版
freemarkerCfg.setServletContextForTemplateLoading(context, "/");
freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8");
try {
//指定模版路径
Template template = freemarkerCfg.getTemplate(templatePath,"UTF-8");
template.setEncoding("UTF-8");
//静态页面路径
String htmlPath = context.getRealPath("/html")+"/"+targetHtmlPath;
File htmlFile = new File(htmlPath);
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));
//处理模版 
template.process(data, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
} 在以上代码中,就会出现问题,直接调用template进行输出时,并没有封装Session,JspTaglibs等对象,所以会报找不到对应对象的错误,也就不能使用Jsp标签了。
可以改为:
Java代码
1.public static void crateHTML(HttpServletRequest request, Map data, 
2. String templatePath, String targetHtmlPath) { 
3. Configuration freemarkerCfg = new Configuration(); 
4. // 加载模版 
5. freemarkerCfg.setServletContextForTemplateLoading(request.getSession() 
6. .getServletContext(), "/"); 
7. freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8"); 
8. try { 
9. // 指定模版路径 
10. Template template = freemarkerCfg 
11. .getTemplate(templatePath, "UTF-8"); 
12. template.setEncoding("UTF-8"); 
13. // 静态页面路径 
14. String htmlPath = request.getSession().getServletContext() 
15. .getRealPath("/html") 
16. + "/" + targetHtmlPath; 
17. File htmlFile = new File(htmlPath); 
18. Writer out = new BufferedWriter(new OutputStreamWriter( 
19. new FileOutputStream(htmlFile), "UTF-8")); 
20. // 处理模版 
21. 
22. data.put("Request", request); 
23. data.put("Session", request.getSession()); 
24. data.put("JspTaglibs", new TaglibFactory(request.getSession() 
25. .getServletContext())); 
26. 
27. template.process(data, out); 
28. out.flush(); 
29. out.c