Freemarker无法使用Session和Taglib

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.close();   
  30.     } catch (Exception e) {   
  31.         e.printStackTrace();   
  32.     }   
  33. }  
	public static void crateHTML(HttpServletRequest request, Map data,
			String templatePath, String targetHtmlPath) {
		Configuration freemarkerCfg = new Configuration();
		// 加载模版
		freemarkerCfg.setServletContextForTemplateLoading(request.getSession()
				.getServletContext(), "/");
		freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8");
		try {
			// 指定模版路径
			Template template = freemarkerCfg
					.getTemplate(templatePath, "UTF-8");
			template.setEncoding("UTF-8");
			// 静态页面路径
			String htmlPath = request.getSession().getServletContext()
					.getRealPath("/html")
					+ "/" + targetHtmlPath;
			File htmlFile = new File(htmlPath);
			Writer out = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(htmlFile), "UTF-8"));
			// 处理模版

			data.put("Request", request);
			data.put("Session", request.getSession());
			data.put("JspTaglibs", new TaglibFactory(request.getSession()
					.getServletContext()));
			
			template.process(data, out);
			out.flush();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

 这时,在ftl模板中就可以调用Request,Session,JspTaglibs等对象了。

 

注:在Struts2中封装的Freemarker视图也不能在ftl模板中使用JspTaglibs对象,可能通过在web.xml文件中配置:

Xml代码 复制代码
  1. <servlet>  
  2.     <servlet-name>JSPSupportServlet</servlet-name>  
  3.     <servlet-class>  
  4.         org.apache.struts2.views.JspSupportServlet   
  5.     </servlet-class>  
  6.     <load-on-startup>1</load-on-startup>  
  7. </servlet>  

 这时,在ftl模板中可以使用Jsp标签了。

http://huajiang.javaeye.com/blog/574220

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值