Grails2.1动态邮件配置

时间:2013-09-24 10:08:13

标签: grails

我正在尝试从Grails应用发送电子邮件。我尝试使用gmail推荐的设置,它工作正常。我成功发了邮件。但我想动态覆盖用户名和密码。我不知道怎么办。有人可以帮忙吗?

    grails {
    mail {
        host = "smtp.gmail.com"
        port = 465
        username = "faruq@gmail.com"    // Want to change dynamically like variable ${branch.mail}
        password = "12345"              // Want to change dynamically like variable ${branch.pass}
        props = [
            "mail.smtp.auth":"true",
            "mail.smtp.socketFactory.port":"465",
            "mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
            "mail.smtp.socketFactory.fallback":"false"
        ]
    }
}

我使用此过程来覆盖控制器中的用户名

grailsApplication.config.grails.mail.username = Branch.get(2).mail

通过此流程用户名成功更改

此处Branch是我的域类,邮件是属性

但出现了身份验证问题:

javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted

现在该怎么办?

3 个答案:

答案 0 :(得分:1)

您可以使用external configuration file - 在主Config.groovy

中添加占位符值
grails {
    mail {
        host = "smtp.gmail.com"
        port = 465
        username = "<changeme>"
        password = "<changeme>"
        props = [
            "mail.smtp.auth":"true",
            "mail.smtp.socketFactory.port":"465",
            "mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
            "mail.smtp.socketFactory.fallback":"false"
        ]
    }
}

然后使用外部配置中的正确值覆盖它们:

grails {
  mail {
    username = "faruq@gmail.com"
    password = "12345"
  }
}

为了能够在运行时动态更改凭据,它变得更加复杂。在封面下,邮件插件创建了一个Spring bean,它是JavaMailSenderImpl的一个实例,用于处理实际发送的电子邮件,默认情况下,此bean配置为配置中的静态设置。但是在运行时,每次需要发送消息时,该类都会显示call its own getUsername() and getPassword()。因此,您可以使用自己的JavaMailSenderImpl自定义子类替换此bean,该子类会覆盖这些方法以从请求上下文中提取详细信息(代码示例,未经过测试,导入/错误处理已省略):

<强>的src /常规/ COM /示例/ RequestCredentialsMailSender.groovy

class RequestCredentialsMailSender extends JavaMailSenderImpl {
  public String getUsername() {
    return RequestContextHolder.requestAttributes?.currentRequest?.mailUsername ?: super.getUsername()
  }

  public String getPassword() {
    return RequestContextHolder.requestAttributes?.currentRequest?.mailPassword ?: super.getPassword()
  }
}

您必须在resources.groovy中注册此bean,并从邮件插件本身复制相当多的配置,这不太理想:

<强>的grails-app / CONF /弹簧/ resources.groovy

beans = {
  mailSender(com.example.RequestCredentialsMailSender) {
    def mailConf = application.config.grails.mail
    host = mailConf.host
    port = mailConf.port
    username = mailConf.username // the default, if not set in request
    password = mailConf.password
    protocol = mailConf.protocol
    javaMailProperties = mailConf.props
  }
}

现在,当您需要从控制器发送邮件时,您可以

request.mailUsername = Branch.get(2).mail
request.mailPassword = Branch.get(2).mailPassword
sendMail { ... }

答案 1 :(得分:0)

只想验证Ian的答案并进行扩展。

在默认的Config.groovy文件中,我添加了外部配置行:

 grails.config.locations = [
     "file:./${appName}-config.groovy",
     "classpath:${appName}-config.groovy"
     ]

....
// and here is the mail config as above
grails{
    mail{
.... 

在根级别的配置文件中,我有我的配置文件:TestApp-config.groovy(其中TestApp是我的应用程序的名称),如上所述:

grails {
  mail {
    username = "faruq@gmail.com"
    password = "12345"
  }
}

过去不需要任何东西,而且效果很好。

答案 2 :(得分:0)

We can also use replyTo field if our aim is only to get the reply back on specific Email Id. We can dynamically pass an email id to "replyTo" field and can expect an email back on the same.

Example :

asynchronousMailService.sendMail { to ["xyz@gmail.com","pqr@gmail.com"] subject "Subject Text" if(ccs) cc ["xyz1@gmail.com","pqr1@gmail.com"] if(bccs) bcc ["xyz2@gmail.com","pqr2@gmail.com"] if(replyTo) replyTo "xyz@gmail.com" if(attachBytes) attachBytes attachBytes } NOTE: Adding "replyTo" will only allow us to get the emails back on the specified email-id and will not send the email from the configured email.

It was suitable in my use case. Hope it helps !