如何在另一个异步线程中使用grails模板呈现方法

时间:2015-10-29 09:51:55

标签: grails asynchronous

我的Grails应用程序正在其中一个控制器中异步发送电子邮件。异步,因为它应该在一个漫长的过程之后发送。我目前正在使用executor插件和runAsync关闭。

def sendEmails() {
    ...
    runAsync {

        // ... Some lengthy process before emailing
        myMailService.send('someone@somecompany.net', 
            g.render(template: 'mail', model: resultOfLengthyProcess))

    }
    ...
}

我在漫长的过程之后运行它,因为render函数调用中的模型包含该过程的结果。

我想使用g.render()方法,因为电子邮件是一个包含大量图片和内容的大型gsp模板。

现在g.render调用将失败,因为它是从另一个线程调用的。它会弹出java.lang.IllegalStateException消息:

  

找不到线程绑定请求:您是指在实际Web请求之外的请求属性,还是在最初接收的线程之外处理请求?如果您实际上是在Web请求中操作并仍然收到此消息,则您的代码可能在DispatcherServlet / DispatcherPortlet之外运行:在这种情况下,请使用RequestContextListener或RequestContextFilter来公开当前请求。

我该如何解决这个问题?我愿意接受任何答案/建议。

1 个答案:

答案 0 :(得分:0)

您需要一个请求才能直接使用渲染,并使用异步块将其丢失。

但是,您应该能够通过在控制器中注入PageRender并从异步块调用它来实现您想要的效果。

class MyController {
    grails.gsp.PageRenderer groovyPageRenderer

    def sendEmails() {
        // ... Some lengthy process before emailing
        myMailService.send(
            'someone@somecompany.net', 
            groovyPageRenderer.render(template: 'mail', model: resultOfLengthyProcess)
        )
    }
}

我建议使用JMS(使用jms插件),将冗长的进程封装在服务中。