我正在使用Grails发送大量HTML电子邮件。我使用SimpleTemplateEngine以这种方式创建我的电子邮件正文:
def ccIdToEmailMap = [:]
def emailTemplateFile = Utilities.retrieveFile("email${File.separator}emailTemplate.gtpl")
def engine = new SimpleTemplateEngine()
def clientContacts = ClientContact.list()
for(ClientContact cc in clientContactList) {
def binding = [clientContact : cc]
//STOPS (FREEZES) EITHER HERE OR....
def template = template = engine.createTemplate(emailTemplateFile).make(binding)
//OR STOPS (FREEZES) HERE
def body = template.toString()
def email = [text: body, to: cc.emailAddress]
ccIdToEmailMap.put(cc.id, email)
println "added to map"
}
return ccIdToEmailMap
以下是我正在尝试为每个电子邮件正文呈现的模板:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Happy Holidays from google Partners</title>
</head>
<body>
<table width="492" cellpadding="0" cellspacing="0" style="border:2px solid #acacac;margin:8px auto;" align="center">
<tr>
<td colspan="5" bgcolor="#c1e0f3"><img src="http://www.google.com/holiday2008/cardbg.gif" width="492" height="10" border="0"></td>
</tr>
<tr>
<td width="6" bgcolor="#c1e0f3"><img src="http://www.google.com/holiday2008/sidebgl.gif" width="6" height="453" border="0"></td>
<td style="background:#fff;border:1px solid #acacac;padding:2px;" width="228">
<div style="width:208px;margin:4px 8px 0px 8px; color:#515151;">
<font face="Times New Roman" size="2">
<span style="font:14px 'Times New Roman',times,serif;">Static text that is the same for each email
<br> <br>
More text
<br> <br>
We wish you health and happiness during the holidays and a year of growth in 2009.
</span>
</font>
</div>
</td>
<td style="background:#c9f4fe;border-top:1px solid #acacac;border-bottom:1px solid #acacac;" width="5"><img src="http://www.google.com/holiday2008/vertbg.gif" border="0" height="453" width="5"></td>
<td width="247" style="background:#fff;border:1px solid #acacac;"><img src="http://www.google.com/holiday2008/snowing.gif" width="247" height="453" border="0"></td>
<td width="6" bgcolor="#c1e0f3"><img src="http://www.google.com/holiday2008/sidebgr.gif" width="6" height="453" border="0"></td>
</tr>
<tr>
<td width="6" bgcolor="#c1e0f3"><img src="http://www.google.com/holiday2008/sidebgr.gif" width="6" height="38" border="0"></td>
<td colspan="3" style="border:1px solid #acacac;" align="center"><img src="http://www.google.com/holiday2008/happyholidays.gif" width="480" height="38" alt="Happy Holidays" border="0"></td>
<td width="6" bgcolor="#c1e0f3"><img src="http://www.google.com/holiday2008/sidebgr.gif" width="6" height="38" border="0"></td>
</tr>
<tr>
<td width="6" bgcolor="#c1e0f3"><img src="http://www.google.com/holiday2008/sidebgr.gif" width="6" height="120" border="0"></td>
<td colspan="3" style="background-color#fff;border:1px solid #acacac;padding:2px;" valign="top">
<img src="http://www.google.com/holiday2008/gogl_logo_card.gif" width="140" height="40" alt="google partners" border="0" align="right" hspace="4" vspace="4" />
<font face="Times New Roman" size="2">
<div style="padding:4px;font:12pt 'Times New Roman',serif;color:#515151;">
<span style="font-size:10pt"><i>from:</i></span>
<div style="padding:2px 4px;">
<% clientContact.owners.eachWithIndex { it, i -> %>
<% if(i < (clientContact.owners.size() - 1)) { %>
${it.toString()},
<% }else { %>
${it.toString()}
<% } %>
<% } %>
</div>
</div>
</font>
</td>
<td width="6" bgcolor="#c1e0f3"><img src="http://www.google.com/holiday2008/sidebgr.gif" width="6" height="120" border="0"></td>
</tr>
<tr>
<td colspan="5" bgcolor="#c1e0f3"><img src="http://www.google.com/holiday2008/cardbg.gif" width="492" height="10" border="0"></td>
</tr>
</table>
</body>
</html>
此方法返回ccIdToEmail地图后,我会发送所有电子邮件。出于某种原因,准备此clientContactIds和电子邮件正文的映射会导致我的应用程序冻结在上面列出的两行中的任何一行。我可以在冻结之前成功准备/发送~140封电子邮件。这种情况非常一致。
有没有人知道为什么这会起作用,但是在从模板创建~140个电子邮件正文后停止工作?我无法在网上找到任何关于其他人遇到麻烦的事情。
安德鲁
答案 0 :(得分:1)
听起来像是同步问题。作为第一步,您应该在循环外部创建模板。由于无需每次都重新创建模板。
def ccIdToEmailMap = [:]
def emailTemplateFile = Utilities.retrieveFile("email${File.separator}emailTemplate.gtpl")
def engine = new SimpleTemplateEngine()
def template = engine.createTemplate(emailTemplateFile)
def clientContacts = ClientContact.list()
for(ClientContact cc in clientContactList)
{
def binding = [clientContact : cc]
def body = template.make(binding).toString()
def email = [text: body, to: cc.emailAddress]
ccIdToEmailMap.put(cc.id, email)
println "added to map"
}
return ccIdToEmailMap
如果它没有帮助,如果您发布模板内容和/或ClientContact的来源可能会有所帮助。
答案 1 :(得分:0)
在模板中延迟加载我的客户联系人所有者时出现了问题。而不是期望所有者被加载(效率低下),而SimpleTemplateEngine正在制作电子邮件正文,我急切地在绑定/制作正文之前获取所有者。
我上面的代码现在看起来像这样:
def emailTemplateFile = null
def ccIdToEmailMap = [:]
emailTemplateFile = Utilities.retrieveFile("email${File.separator}emailTemplate.gtpl")
def engine = new SimpleTemplateEngine()
def template = engine.createTemplate(emailTemplateFile)
for(ClientContact cc in clientContactList)
{
//there was a locking problem when we tried to create the template for too many client contacts
//i believe it was caused by lazy-fetching of the person/owners. So, I fetch them before we bind
//and make the email body.
def criteria = ClientContact.createCriteria()
cc = criteria.get {
eq("id", cc.id)
fetchMode('relationship', FM.EAGER)
fetchMode('relationship.person', FM.EAGER)
}
def binding = [clientContact : cc]
def body = template.make(binding).toString()
def email = [text: body, to: cc.emailAddress]
ccIdToEmailMap.put(cc.id, email)
}
return ccIdToEmailMap
对每个客户端联系人进行大量查询仍然效率低下,但IT工作正常。我无法解释为什么在模板制作过程中延迟加载它们导致grails / groovy冻结,但确实如此。如果有人能够解释,我会很感激。
感谢您的回答。齐格弗里德......你让我开始朝着正确的方向前进。
安德鲁