通过metaClass在Grails Email Plugin中添加/修改密件抄送

时间:2014-04-18 00:33:17

标签: grails grails-plugin

我正在尝试拦截并可能修改对mailService.sendMail的所有来电,以便为发送的电子邮件添加/修改bcc。这是一个临时实验,所以我希望尽可能避免查找/更改所有现有代码。

示例:

mailService.sendMail {
    to 'my_email@provider.com'
    //bcc may be present
    from 'admin@mysystem.com'
    subject 'Hello'
    body 'Just testing'
}

我可以使用在Bootstrap中创建的内容轻松拦截调用:

mailService.metaClass.invokeMethod = {String name, args ->
    println "intercepting for ${name}..."
    def res = delegate.metaClass.getMetaMethod(name, args).invoke(delegate, args)
    println "done intercepting"
}

我完全不知道如何实际修改调用,如果没有,则添加一个密件抄送,或者如果它存在则添加一个地址。 args参数是关闭 - 我已经查看了关于该主题的所有内容并且没有任何乐趣。

这是在Grails 1.3.7(我知道)上运行。

1 个答案:

答案 0 :(得分:2)

无论先前定义的bcc如何,总是可以添加bcc的一种方法是将原始闭包arg与新的闭包组成:

mailService.metaClass.invokeMethod = {String name, args ->

    if( name == 'sendMail' ) {

        def newArgs = args[0] >> { bcc 'hr@mysystem.com' }

        //or def newArgs = { bcc 'hr@mysystem.com' } << args[0]

        def res = delegate.metaClass.getMetaMethod(name, newArgs)
                                    .invoke(delegate, newArgs)
    }
}

假设邮件应该是密件抄送且bcc列表保持不变,这样我们就不必跟踪提供的bcc列表。确保方法的名称始终被检查为sendMail,以避免对其他方法进行拦截,尽管所有方法都将在mailService bean中被截获,但除sendMail之外的其他方法将跳过这些方法。

<强>更新
封闭组合可从Groovy 1.8获得,我非常怀疑Groovy 1.8可用于Grails 1.3.7。在这种情况下,您可以尝试以下方法:

mailService.metaClass.invokeMethod = {String name, args ->
    if(name == 'sendMail') {
        println "intercepting for ${name}..."

        def newClos = { cl -> 
            return {
                cl.delegate = delegate
                cl.resolveStrategy = Closure.DELEGATE_FIRST
                cl()

                //bcc
                bcc 'hr@mysystem.com'
            }
        }

        def newArgs = newClos args[0]
        def res = delegate.metaClass.getMetaMethod(name, newArgs)
                                    .invoke(delegate, newArgs)
        println "done intercepting"
    }
}