好的,畢竟它並不那麼辛苦。簡單的步驟,第一:
第一步:準備數據庫表來存放待處理的電子郵件記錄:
class PendingEmail {
Date sentAt = new Date()
String fileName
static constraints = {
sentAt nullable: false
fileName nullable: false, blank:false
}
}
第二步:創建一個週期性的任務發送掛起的電子郵件。 (!和它的配置) - 注意:mailSender
注射是原創的Grails郵件插件的一部分,因此發送通過郵件插件製作:
import javax.mail.internet.MimeMessage
class BackgroundEmailSenderJob {
def concurrent = false
def mailSender
static triggers = {
simple startDelay:15000l, repeatInterval: 30000l, name: "Background Email Sender"
}
def execute(context){
log.debug("sending pending emails via ${mailSender}")
// 100 at a time only
PendingEmail.list(max:100,sort:"sentAt",order:"asc").each { pe ->
// FIXME: do in transaction
try {
log.info("email ${pe.id} is to be sent")
// try to send
MimeMessage mm = mailSender.createMimeMessage(new FileInputStream(pe.fileName))
mailSender.send(mm)
// delete message
log.info("email ${pe.id} has been sent, deleting the record")
pe.delete(flush:true)
// delete file too
new File(pe.fileName).delete();
} catch(Exception ex) {
log.error(ex);
}
}
}
}
第三步:創建一個下拉更換MailService的那可以被任何Grails代碼使用,包括插件。注意mmbf注入:這是來自Mail Plugin的mailMessageBuilderFactory
。該服務使用出廠序列化進入封閉的呼叫到一個有效的MIME消息,然後將其保存到文件系統:
import java.io.File;
import org.springframework.mail.MailMessage
import org.springframework.mail.javamail.MimeMailMessage
class MyMailService {
def mmbf
MailMessage sendMail(Closure callable) {
log.info("sending mail using ${mmbf}")
if (isDisabled()) {
log.warn("No mail is going to be sent; mailing disabled")
return
}
def messageBuilder = mmbf.createBuilder(mailConfig)
callable.delegate = messageBuilder
callable.resolveStrategy = Closure.DELEGATE_FIRST
callable.call()
def m = messageBuilder.finishMessage()
if(m instanceof MimeMailMessage) {
def fil = File.createTempFile("mail", ".mime")
log.debug("writing content to ${fil.name}")
m.mimeMessage.writeTo(new FileOutputStream(fil))
def pe = new PendingEmail(fileName: fil.absolutePath)
assert pe.save(flush:true)
log.debug("message saved for sending later: id ${pe.id}")
} else {
throw new IllegalArgumentException("expected MIME")
}
}
def getMailConfig() {
org.codehaus.groovy.grails.commons.ConfigurationHolder.config.grails.mail
}
boolean isDisabled() {
mailConfig.disabled
}
}
第四步:與修改後的版本替換郵件插件的MailService的,與注射它工廠。 grails-app/conf/spring/resources.groovy
:
beans = {
mailService(MyMailService) {
mmbf = ref("mailMessageBuilderFactory")
}
}
完成!
從現在開始,任何使用/注入mailService的插件或Grails代碼都將獲得對MyMailService的引用。該服務將接收發送電子郵件的請求,但不會發送它,而是將其序列化到磁盤上,並將記錄保存到數據庫中。定期任務將每30秒加載一堆這樣的記錄,並嘗試使用原始郵件插件服務發送它們。
我測試了它,它似乎工作正常。我需要在這裏和那裏進行清理,在發送時添加事務範圍,使參數可配置等等,但骨架已經是可行的代碼。
希望能幫助別人。
是的,我認爲代碼會幫助我,謝謝,因爲我將我的web應用程序部署到Linux主機環境。我可以問你,你爲SMTP服務器決定了什麼。你有沒有發現任何簡單和輕鬆..它在您的服務器上運行? – Ray 2011-08-24 02:13:43
我開發的SMTP是在我的開發箱上運行的postfix; PROD中的SMTP是我的託管公司使用的。我不在乎他們運行的是什麼(我相信這是qmail,但可能會誤解)。 – 2011-08-25 14:51:21