3

我们目前正在使用同步。网络电话发送电子邮件。这是为了证明一些基本功能的快速修复,但现在我们需要异步发送电子邮件。我已经对所有内容进行了重新设计以排队作业然后发送电子邮件,但我遇到了一个问题。我们将 FTL 用于我们的电子邮件模板,并且在我们将 servlet 上下文传递给 FTL 以获取模板文件夹之前。由于我们现在在由 Spring @Scheduled 作业处理的排队作业中执行此操作,因此我们不再有权访问 Web servlet。我已经研究和玩了一段时间了,但我似乎还没有想出一种真正可行的方法。

我有一种感觉有一些超级简单的方法可以得到

之前完成这项工作的代码与此类似:

@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)
    }
4

1 回答 1

1

尽管这篇文章已经很老了,并且作者已经尝试了另一种解决方案,但没有必要为了加载模板而拥有一个 servlet 上下文实例。freemarker 文档指出:

内置模板加载器

您可以使用以下便捷方法在配置中设置三种模板加载方法。(每个方法都会在内部创建一个模板加载器对象并设置配置实例来使用它。)

void setDirectoryForTemplateLoading(File dir);   

或者

void setClassForTemplateLoading(Class cl, String prefix);   

或者

void setServletContextForTemplateLoading(Object servletContext, String path);

http://freemarker.org/docs/pgui_config_templateloading.html

因此,在这种情况下,应该可以通过命名与模板处于同一级别的类来配置 freemarker 以使用 ClassLoader(选项 2),或者使用此类作为根节点以使用相对路径导航到模板。

于 2014-07-31T09:59:06.783 回答