Servlets 在JavaEE服务器中使用Freemarker和Restlet2.0
我对Freemarker和Restlet的Freemarker扩展的文档中所写的内容有点困惑 情况是这样的:restlet引擎提供资源的HTML表示(例如www.mysite.com/{user}/updates)。为此URI返回的资源是一个包含所有更新的HTML页面,该页面是使用freemarker模板创建的。此应用程序托管在Glassfish v3服务器上 问题: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文档,freemarker配置只应加载一次:
在JavaEE应用程序中,什么是执行此操作的最佳位置?我正在考虑将其作为web.xml中的上下文参数,并使用ServletContextListener,但我不知道如何去做/* 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());
- 根据freemarker的文档,我们还可以向其中添加freemarkerservlet和map.ftl url模式。但这已经由restletservlet映射(即“/”的url模式)。因此,为*.ftl再买一个是没有意义的(或者说是吗?)
谢谢 这的确是一个棘手的问题。要求我完成org.restlet.ext.Freemarker包中源文件的实现-呸 这是你可以做到的
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;
- 如果您确实得到一个协议不受支持的异常,它将出现在案例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;
}
}