无法理解 Scala 中的 WS 库
Trouble understanding WS library in Scala
我正在尝试使用 play 框架学习 scala,并且我正在尝试完全用 scala 重写一个旧项目以供练习。我已经编写了一条路线,用于注册新订阅者并使用 mandrill 向他们发送一封感谢订阅的电子邮件。我也有一些基本的错误检查。代码如下
def create = Action.async(parse.json) { request =>
request.body.validate[Subscriber].map {subscriber =>
if (!isValidEmail(subscriber.email)){
Future.successful(BadRequest(Json.obj("message"->"Invalid email address")))
}
else{
collection.insert(subscriber).map {lastError =>
val data = Json.obj(
"key" -> Play.current.configuration.getString("mandrill.key").get,
"template_name" -> "Initial Email",
"template_content" -> Json.arr(),
"message" -> Json.obj(
"subject"-> "Example",
"from_email"-> "info@example.org",
"from_name" -> "example",
"to"-> Json.arr(
Json.obj(
"email"-> subscriber.email,
"name"-> subscriber.fname,
"type"-> "to"
)
)
)
)
WS.url("https://mandrillapp.com/api/1.0/messages/send-template.json").post(data)
Ok(Json.obj("message"->"User created successfully"))
}
.recover {
case e: Throwable => BadRequest(Json.obj("message" -> "A user with email ${subscriber.email} already exists"))
}
}
}.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters"))))
}
这行得通,但我想阻止 WS 调用,这样我就可以在发回成功消息之前等待它的响应,因为我想 return 如果 mandrill 发回错误消息给我一个错误.所以我正在尝试做这样的事情:
def create = Action.async(parse.json) { request =>
request.body.validate[Subscriber].map {subscriber =>
if (!isValidEmail(subscriber.email)){
Future.successful(BadRequest(Json.obj("message"->"Invalid email address")))
}
else{
collection.insert(subscriber).map {lastError =>
val data = Json.obj(
"key" -> Play.current.configuration.getString("mandrill.key").get,
"template_name" -> "Initial Email",
"template_content" -> Json.arr(),
"message" -> Json.obj(
"subject"-> "Example",
"from_email"-> "info@example.org",
"from_name" -> "example",
"to"-> Json.arr(
Json.obj(
"email"-> subscriber.email,
"name"-> subscriber.fname,
"type"-> "to"
)
)
)
)
//This line right below doesn't work
WS.url("https://mandrillapp.com/api/1.0/messages/send-template.json").post(data).map{response =>
if (response.status == 200){
Ok(Json.obj("message"->"User created successfully"))
}
else {
BadRequest(Json.obj("message"->"Unknown error"))
}
}
}
.recover {
case e: Throwable => BadRequest(Json.obj("message" -> "A user with email ${subscriber.email} already exists"))
}
}
}.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters"))))
}
但这会出现以下错误
type mismatch;
found : scala.concurrent.Future[Object]
required: scala.concurrent.Future[play.api.mvc.Result]
在线
}.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters"))))
谁能给我解释一下。我不想使用等待。我只想使用 map 以便获得结果、处理它们然后发回 "Ok" 消息。我正在使用 play 2.3.x 和 scala 2.11
您似乎在 collection.insert
的 map
块内调用 WS
。 map
期望你 return 一个 play.api.mvc.Result
,但是 WS.post
和你附加的 map
,return 一个 Future[play.api.mvc.Result]
.
鉴于 Future.successful(BadRequest(Json.obj("message"->"Invalid email address")))
returns Future[play.api.mvc.Result]
和你的 collection.insert
returns a Future[Future[play.api.mvc.Result]]
常见的推断类型是 Future[Object]
如果您将 collection.insert
上的 map
更改为 flatMap
,即表示您打算 return Future[play.api.mvc.Result]
而不是 play.api.mvc.Result
],你应该让类型排队,例如:
def create = Action.async(parse.json) { request =>
request.body.validate[Subscriber].map { subscriber =>
if (!isValidEmail(subscriber.email)){
Future.successful(BadRequest(Json.obj("message"->"Invalid email address")))
} else {
collection.insert(subscriber).flatMap { lastError =>
val data = Json.obj(
"key" -> Play.current.configuration.getString("mandrill.key").get,
"template_name" -> "Initial Email",
"template_content" -> Json.arr(),
"message" -> Json.obj(
"subject"-> "Example",
"from_email"-> "info@example.org",
"from_name" -> "example",
"to"-> Json.arr(
Json.obj(
"email"-> subscriber.email,
"name"-> subscriber.fname,
"type"-> "to"
)
)
)
)
WS.url("https://mandrillapp.com/api/1.0/messages/send-template.json")
.post(data).map{ response =>
if (response.status == 200) {
Ok(Json.obj("message"->"User created successfully"))
} else {
BadRequest(Json.obj("message"->"Unknown error"))
}
}
}.recover {
case e: Throwable => BadRequest(Json.obj("message" -> "A user with email ${subscriber.email} already exists"))
}
}
}.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters"))))
}
我正在尝试使用 play 框架学习 scala,并且我正在尝试完全用 scala 重写一个旧项目以供练习。我已经编写了一条路线,用于注册新订阅者并使用 mandrill 向他们发送一封感谢订阅的电子邮件。我也有一些基本的错误检查。代码如下
def create = Action.async(parse.json) { request =>
request.body.validate[Subscriber].map {subscriber =>
if (!isValidEmail(subscriber.email)){
Future.successful(BadRequest(Json.obj("message"->"Invalid email address")))
}
else{
collection.insert(subscriber).map {lastError =>
val data = Json.obj(
"key" -> Play.current.configuration.getString("mandrill.key").get,
"template_name" -> "Initial Email",
"template_content" -> Json.arr(),
"message" -> Json.obj(
"subject"-> "Example",
"from_email"-> "info@example.org",
"from_name" -> "example",
"to"-> Json.arr(
Json.obj(
"email"-> subscriber.email,
"name"-> subscriber.fname,
"type"-> "to"
)
)
)
)
WS.url("https://mandrillapp.com/api/1.0/messages/send-template.json").post(data)
Ok(Json.obj("message"->"User created successfully"))
}
.recover {
case e: Throwable => BadRequest(Json.obj("message" -> "A user with email ${subscriber.email} already exists"))
}
}
}.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters"))))
}
这行得通,但我想阻止 WS 调用,这样我就可以在发回成功消息之前等待它的响应,因为我想 return 如果 mandrill 发回错误消息给我一个错误.所以我正在尝试做这样的事情:
def create = Action.async(parse.json) { request =>
request.body.validate[Subscriber].map {subscriber =>
if (!isValidEmail(subscriber.email)){
Future.successful(BadRequest(Json.obj("message"->"Invalid email address")))
}
else{
collection.insert(subscriber).map {lastError =>
val data = Json.obj(
"key" -> Play.current.configuration.getString("mandrill.key").get,
"template_name" -> "Initial Email",
"template_content" -> Json.arr(),
"message" -> Json.obj(
"subject"-> "Example",
"from_email"-> "info@example.org",
"from_name" -> "example",
"to"-> Json.arr(
Json.obj(
"email"-> subscriber.email,
"name"-> subscriber.fname,
"type"-> "to"
)
)
)
)
//This line right below doesn't work
WS.url("https://mandrillapp.com/api/1.0/messages/send-template.json").post(data).map{response =>
if (response.status == 200){
Ok(Json.obj("message"->"User created successfully"))
}
else {
BadRequest(Json.obj("message"->"Unknown error"))
}
}
}
.recover {
case e: Throwable => BadRequest(Json.obj("message" -> "A user with email ${subscriber.email} already exists"))
}
}
}.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters"))))
}
但这会出现以下错误
type mismatch;
found : scala.concurrent.Future[Object]
required: scala.concurrent.Future[play.api.mvc.Result]
在线
}.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters"))))
谁能给我解释一下。我不想使用等待。我只想使用 map 以便获得结果、处理它们然后发回 "Ok" 消息。我正在使用 play 2.3.x 和 scala 2.11
您似乎在 collection.insert
的 map
块内调用 WS
。 map
期望你 return 一个 play.api.mvc.Result
,但是 WS.post
和你附加的 map
,return 一个 Future[play.api.mvc.Result]
.
鉴于 Future.successful(BadRequest(Json.obj("message"->"Invalid email address")))
returns Future[play.api.mvc.Result]
和你的 collection.insert
returns a Future[Future[play.api.mvc.Result]]
常见的推断类型是 Future[Object]
如果您将 collection.insert
上的 map
更改为 flatMap
,即表示您打算 return Future[play.api.mvc.Result]
而不是 play.api.mvc.Result
],你应该让类型排队,例如:
def create = Action.async(parse.json) { request =>
request.body.validate[Subscriber].map { subscriber =>
if (!isValidEmail(subscriber.email)){
Future.successful(BadRequest(Json.obj("message"->"Invalid email address")))
} else {
collection.insert(subscriber).flatMap { lastError =>
val data = Json.obj(
"key" -> Play.current.configuration.getString("mandrill.key").get,
"template_name" -> "Initial Email",
"template_content" -> Json.arr(),
"message" -> Json.obj(
"subject"-> "Example",
"from_email"-> "info@example.org",
"from_name" -> "example",
"to"-> Json.arr(
Json.obj(
"email"-> subscriber.email,
"name"-> subscriber.fname,
"type"-> "to"
)
)
)
)
WS.url("https://mandrillapp.com/api/1.0/messages/send-template.json")
.post(data).map{ response =>
if (response.status == 200) {
Ok(Json.obj("message"->"User created successfully"))
} else {
BadRequest(Json.obj("message"->"Unknown error"))
}
}
}.recover {
case e: Throwable => BadRequest(Json.obj("message" -> "A user with email ${subscriber.email} already exists"))
}
}
}.getOrElse(Future.successful(BadRequest(Json.obj("message" -> "Not enough parameters"))))
}