scala Play Framework 2.4: отправка электронной почты

Я пытаюсь отправить электронное письмо из scala Play framework 2.4, используя play-mailer. инструкции со своей страницы образца, но безуспешно.

Я добавил зависимость в build.sbt:

libraryDependencies ++= Seq(
  "com.typesafe.play" %% "play-mailer" % "3.0.1"
)

В application.conf я добавил следующее:

play.mailer {
    host=smtp.gmail.com
    port=465 
    ssl=true
    tls=true
    user="[email protected]"
    password=abracadabra
}

И, наконец, класс рассылки:

package controllers

import java.io.File
import javax.inject.Inject
import org.apache.commons.mail.EmailAttachment
import play.api.Configuration
import play.api.Play.current
import play.api.libs.mailer._

class Mail(mailer: MailerClient) {
  def send = {
    val cid = "1234"
    val email = Email(
      "Simple email",
      "Mister FROM <[email protected]>",
      Seq("Miss TO <[email protected]>"),
      bodyText = Some("A text message"),
      bodyHtml = Some("some data....")
    )
    mailer.send(email)
  }
}

Пока без ошибок компиляции, однако я не понимаю, как инициализировать этот класс... как мне получить экземпляр "MailerClient"?

В документации написано «Тогда в определении маршрутизатора используйте трейт MailerComponents» со следующим примером кода:

import play.api._
import play.api.ApplicationLoader.Context
import router.Routes
import play.api.libs.mailer._

class MyApplicationLoader extends ApplicationLoader {
  def load(context: Context) = {
    new ApplicationComponents(context).application
  }
}

class ApplicationComponents(context: Context) extends BuiltInComponentsFromContext(context) with MailerComponents {
  lazy val myComponent = new MyComponent(mailerClient)
  // create your controllers here ...
  lazy val router = new Routes(...) // inject your controllers here
}

(Я добавил "play.application.loader=SimpleApplicationLoader" в application.conf)

но я получаю следующие ошибки компиляции:

D:\myApp\app\SimpleApplicationLoader.scala:12: not found: type MailerComponents

[error] class ApplicationComponents(context: Context) extends BuiltInComponentsFromContext(context) with MailerComponents {
[error]                                                                                                  ^
[error] D:\myApp\app\SimpleApplicationLoader.scala:13: not found: value mailerClient
[error]   lazy val applicationController = new controllers.Mail(mailerClient)
[error]                                                         ^
[error] two errors found
[error] (compile:compileIncremental) Compilation failed

Есть идеи?


person Jenny    schedule 26.09.2015    source источник


Ответы (2)


Вы можете использовать инъекцию зависимостей во время выполнения, как предложил другой ответ. Но если вы хотите использовать свой текущий подход, читайте дальше...

Проблема в том, что черта MailerComponents не существует в ветка 3.x. похоже, он существует в главная ветка, но не в их следующая ветка. Я не уверен, что они там делают.

Если вы хотите продолжить работу с примером, вам нужно немного повозиться и выяснить, как его скомпилировать. Например Немного осмотревшись, я пришел к следующему.

import play.api._
import play.api.ApplicationLoader.Context
import router.Routes
import play.api.libs.mailer._

class SimpleApplicationLoader extends ApplicationLoader {
  def load(context: Context) = {
    new ApplicationComponents(context).application
  }
}

class ApplicationComponents(context: Context) extends BuiltInComponentsFromContext(context) {
  val mailerClient = new CommonsMailer(configuration)
  lazy val applicationController = new controllers.ApplicationScala(mailerClient)
  lazy val assets = new controllers.Assets(httpErrorHandler)
  lazy val router = new Routes(httpErrorHandler, applicationController)
}

По сути, вместо того, чтобы полагаться на несуществующий MailerComponent для создания mailerClient для меня, я просто сделал это сам.

Если у вас есть следующая строка в controllers.ApplicationScala

val id = mailer.configure(Configuration.from(Map("host" -> "typesafe.org", "port" -> 1234))).send(email)

Замените его на:

val id = mailer.send(email)

И он будет компилироваться. Между тем, я думаю, что должен поднять вопрос об этом на github. И, может быть, вы должны.

person Bhashit Parikh    schedule 29.09.2015
comment
Спасибо Бхашит! Поскольку текущий подход не работал, я пытался отправлять электронные письма с внедрением зависимостей во время выполнения. Теперь я не могу понять, как вызвать отправку. Я не хочу делать это с помощью действия, но отправлять уведомление по электронной почте каждый раз, когда происходит одно из нескольких других действий... если я попытаюсь выполнить controllers.Mailer.send() из одного моей функции действия я получаю следующую ошибку компиляции: object Mailer is not a member of package controllers [error] Note: class Mailer exists, but it has no companion object. - person Jenny; 29.09.2015
comment
@ Дженни, похоже, вы не создаете экземпляр класса Mailer. Вы не можете использовать controllers.Mailer.send() напрямую (как в маршрутах). Если вы используете DI во время выполнения, попробуйте внедрить экземпляр Mailer в свои контроллеры. И я думаю, что класс Mailer не должен быть частью пакета контроллера. - person Bhashit Parikh; 29.09.2015

Я считаю, что вы могли бы просто позволить игровой платформе внедрить почтовый клиент. Настройка конфигурации и аннотация вашего конструктора с помощью @Inject() должны работать. Объявление вашего контроллера Mail будет выглядеть так:

class Mail @Inject() (mailer: MailerClient) {
person Łukasz    schedule 27.09.2015
comment
Спасибо Лукаш. С внедрением зависимостей во время выполнения я не могу понять, как вызвать отправку. Я не хочу делать это с помощью действия, но отправлять уведомление по электронной почте каждый раз, когда происходит одно из нескольких других действий... если я попробуйте выполнить controllers.Mailer.send() из одной из моих функций действия. Я получаю следующую ошибку компиляции: object Mailer is not a member of package controllers [error] Note: class Mailer exists, but it has no companion object. - person Jenny; 29.09.2015
comment
хорошо, если вы находитесь в другом классе и хотите выполнить метод класса Mail, вам понадобится его экземпляр, который вы также можете попросить ввести class MyOtherClass @Inject() (mailer: Mailer) - person Łukasz; 29.09.2015