我们目前正在使用同步。网络电话发送电子邮件。这是为了证明一些基本功能的快速修复,但现在我们需要异步发送电子邮件。我几乎对所有工作进行了重做以排队作业然后发送电子邮件,但我遇到了一个问题。我们将 FTL 用于我们的电子邮件模板,并且在将 servlet 上下文传递给 FTL 以获取模板文件夹之前。由于我们现在在一个由 Spring @Scheduled 作业处理的排队作业中执行此操作,因此我们无法再访问 Web servlet。我已经研究和玩了一段时间了,但我似乎还没有想出一种实际可行的方法。
我觉得有一些 super 简单的方法可以得到
之前完成这项工作的代码看起来与此类似:
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Path("someStuffHere")
@Transactional
public function someWebServiceCall(@Context javax.servlet.http.HttpServletRequest req)
{
SomeStuff foo = gotSomeStuff();
sendEmail(req.getServlet(), foo);
}
public sendEmail(Servlet context, SomeStuff foo) //<-- lives in another class somewhere, just showing how FTL uses the servlet
{
Configuration cfg = new Configuration();
cfg.setServletContextForTemplateLoading(context,"communicationTemplates/email");
}
新代码现在看起来像这样:
public class someClass
{
@Autowired
private SomeRepo someRepo;
@Scheduled(cron = "* */2 * * * ?")
public void sendAnyOutstandingStuffEmails()
{
SomeStuff foo = someRepo.getStuff();
sendEmail(/*how to get context, or a resource so FTL can get the template folder*/, foo)
}
最佳答案
尽管这篇文章已经很老了,而且作者已经尝试了另一种解决方案,但加载模板并不是必须要有 servlet 上下文实例。 freemarker 文档指出:
Built-in template loaders
You can set up three template loading methods in the Configuration using the following convenience methods. (Each method will create a template loader object internally and set up the Configuration instance to use that.)
void setDirectoryForTemplateLoading(File dir);
or
void setClassForTemplateLoading(Class cl, String prefix);
or
void setServletContextForTemplateLoading(Object servletContext, String path);
http://freemarker.org/docs/pgui_config_templateloading.html
所以在这种情况下,应该可以配置 freemarker 以使用 ClassLoader(选项 2),方法是命名一个与模板处于同一级别的类,或者将此类作为根使用使用相对路径导航到模板的节点。
关于java - 当不在 web Servlet 中时,在 FTL/spring 中获取模板的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19599162/