Servlets 在JavaEE服务器中使用Freemarker和Restlet2.0

Servlets 在JavaEE服务器中使用Freemarker和Restlet2.0,servlets,jakarta-ee,freemarker,restlet,restlet-2.0,Servlets,Jakarta Ee,Freemarker,Restlet,Restlet 2.0,我对Freemarker和Restlet的Freemarker扩展的文档中所写的内容有点困惑 情况是这样的:restlet引擎提供资源的HTML表示(例如www.mysite.com/{user}/updates)。为此URI返回的资源是一个包含所有更新的HTML页面,该页面是使用freemarker模板创建的。此应用程序托管在Glassfish v3服务器上 问题: 根据freemarker文档,freemarker配置只应加载一次: /* You should do this ON

我对Freemarker和Restlet的Freemarker扩展的文档中所写的内容有点困惑

情况是这样的:restlet引擎提供资源的HTML表示(例如www.mysite.com/{user}/updates)。为此URI返回的资源是一个包含所有更新的HTML页面,该页面是使用freemarker模板创建的。此应用程序托管在Glassfish v3服务器上

问题:

  • 根据freemarker文档,freemarker配置只应加载一次:

        /* You should do this ONLY ONCE in the whole application life-cycle:Create and adjust the configuration */
        Configuration cfg = new Configuration();
        cfg.setDirectoryForTemplateLoading(
                new File("/where/you/store/templates"));
        cfg.setObjectWrapper(new DefaultObjectWrapper());
    
    在JavaEE应用程序中,什么是执行此操作的最佳位置?我正在考虑将其作为web.xml中的上下文参数,并使用ServletContextListener,但我不知道如何去做

  • 根据freemarker的文档,我们还可以向其中添加freemarkerservlet和map.ftl url模式。但这已经由restletservlet映射(即“/”的url模式)。因此,为*.ftl再买一个是没有意义的(或者说是吗?)

因此,问题基本上是如何最好地与Freemarker的“配置”集成,使其只发生一次,以及该代码的“入口点”(谁调用它)是什么。有人在JavaEE环境中成功地使用了Freemarker+restlet吗?有什么想法吗


谢谢

这的确是一个棘手的问题。要求我完成org.restlet.ext.Freemarker包中源文件的实现-呸

这是你可以做到的

  • 如果需要创建自己的配置对象,请将“templateLoader”设置为使用,然后让TemplateRepresentation“工作”以进行渲染:

    Configuration cfg = new Configuration();
    
    ContextTemplateLoader loader = new ContextTemplateLoader(getContext(),"war:///WEB-INF");
    
    cfg.setTemplateLoader(loader);
    
    TemplateRepresentation rep = null;
    
    Mail mail = new Mail(); //The data object you wish to populate - example from Restlet itself
        mail.setStatus("received");
        mail.setSubject("Message to self");
        mail.setContent("Doh!");
        mail.setAccountRef(new Reference(getReference(), "..").getTargetRef()
                .toString());
    
      Map<String, Object> data = new HashMap<String, Object>();
      data.put("status", mail.getStatus());
      data.put("subject", mail.getSubject());
      data.put("content", mail.getContent());
      data.put("accountRef", mail.getAccountRef());
    
      rep = new TemplateRepresentation("Mail.ftl", cfg, data, MediaType.TEXT_HTML);
    
      return rep;
    
  • 如果要初始化配置对象一次,并通过调用配置对象上的setServletContextForTemplateLoading(…)方法来设置模板。您始终可以在ServletContextListener中执行此操作

  • 然后调用静态getFMConfig()并将其传递给TemplateRepresentation,如图1所示

    注意事项:

    • 如果您确实得到一个协议不受支持的异常,它将出现在案例2中。这意味着ServerResource不知道使用什么协议来访问文件——这将是Restlet的CLAP协议。您可能需要在web.xml文件中为RestletServlet设置init参数,并将CLAP作为参数值之一
    • TemplateRepresentation有很多构造函数——如果在实例化过程中没有传入配置对象(使用另一个重载构造函数),它将为您创建一个新的configuration()。因此,您不必像第2节那样进行任何配置设置(这可能会让您觉得很明显,但我假设您仍然需要设置配置,或者它会“从某处获取配置”)
    • 如果您确实希望拥有自己的配置设置,则必须将其传递给一个构造函数
    • 查看1中ContextTemplateLoader构造函数中的“war://”字符串这很重要没有在哪里提到baseUri引用应该是什么,即使在文档中也没有提到。我尝试了很长一段时间,才发现它应该是“war://”,后跟存储模板的文件夹名
    • 对于案例2,您可能必须将模板存储在与从中访问此代码的类文件相同的包中。如果仔细观察,您会注意到一个LocalReference参数作为ClientResource的参数,表示资源应该在本地存在,因此您需要使用自定义CLAP协议(classLoader访问协议)
    个人挫败点-为什么文档或任何地方都没有澄清这一切:)


    希望它能帮助那些偶然发现这篇文章的人!呸

    选项2适合我。我想使用选项1,但我始终没有发现模板错误。你能给我解释一下这个的目录结构吗?@bvamos-应该可以。我的示例代码适用于在根级别的WEB-INF文件夹中找到的所有模板。如果有嵌套文件夹,则需要适当设置路径。你的模板在哪里?你如何调用
    ContextTemplateLoader
    的构造函数?@PhD-谢谢你的回复。我已经用cfg.setTemplateLoader(新的ClassTemplateLoader(getClass(),“templates/”)和cfg.getTemplate(filename)解决了这个问题,它非常适合我,可以与war包一起使用。
    //Load the FreeMarker template
        Representation mailFtl = new ClientResource(
                LocalReference.createClapReference(getClass().getPackage())
                        + "/Mail.ftl").get(); 
      //Wraps the bean with a FreeMarker representation
    return new TemplateRepresentation(mailFtl, mail, MediaType.TEXT_HTML);
    
    
    public class Config implements ServletContextListener {
        private static Configuration cfg = new Configuration();
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            ServletContext sc = sce.getServletContext();
            cfg.setServletContextForTemplateLoading(sc, "/WEB-INF");        
        }
        public static Configuration getFMConfig()
        {
            return cfg;
        }
    }