我的工作(学习)在一分钟斯卡拉/播放,我需要发送POST请求外部URL,然后取决于响应状态代码,做1 2的东西,
如果200推响应数据到视图并显示它。 如果400显示错误页面。
我写了一个连接器看起来像这样,
package connectors
import com.google.inject.Inject
import config.AppConfig
import play.api.libs.json.Json
import play.api.libs.ws.{WSClient, WSResponse}
import play.mvc.Http.Status
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import play.api.libs.json._
class RegisterConnector @Inject() (appConfig: AppConfig, ws: WSClient) {
val customerBaseUrl: String = appConfig.customerBaseUrl
def verifyCustomer(code: String): Future[Boolean] = {
ws.url(s"$customerBaseUrl/customer/$code").post(code).map(processResponseStatus)
}
private def processResponseStatus(resp: WSResponse): Boolean = resp.status match {
case code if (Status.OK until Status.MULTIPLE_CHOICES).contains(code) => true
case _ => throw new RegisterException(s"Server error: ${resp.status} . ${resp.body}");
}
}
class RegisterException(message: String) extends RuntimeException(message: String)
然后我用我的连接器在我的控制器,但我不能制定出一个)如何解析响应,如果状态代码为200,和B如何检测错误,任何人都可以帮我请,这里是我的电流控制器,
package controllers
import com.google.inject.{Inject, Singleton}
import config.AppConfig
import play.api.i18n.{I18nSupport, MessagesApi}
import play.api.mvc._
import scala.concurrent._
import ExecutionContext.Implicits.global
import connectors.RegisterConnector
import play.api.Logger
import views.html.register.verified
@Singleton
class VerifiedController @Inject()(registerConnector: RegisterConnector,
val messagesApi: MessagesApi)
(implicit appConfig: AppConfig) extends Controller with I18nSupport {
def verify(code: String): Action[AnyContent] = Action.async { implicit request: Request[AnyContent] =>
registerConnector.verifyCustomer(code).map {
case true =>
case _ =>
}.recover {
case ex =>
}
}
def show(): Action[AnyContent] = Action { implicit request: Request[AnyContent] =>
Ok(verified())
}
def error(): Action[AnyContent] = Action { implicit request: Request[AnyContent] =>
Ok(verified())
}
}
一些帮助和指导将是非常美妙!
假设JSON是响应格式,我通常开始的情况下类包装的响应结构。假设下面的JSON响应:
{
"city": "Vienna",
"forecast": 10
}
现在的情况下,情况是这样的:
case class WeatherUpdate(city: String, forecast: Int)
使用单让你的API调用的策略是相当不错的。让我们把这个家伙WeatherService
。而不是返回Future[Boolean]
你可以使用Scala的标准库Try
。
class WeatherService @Inject() (ws: WSClient) {
private val logger = Logger(getClass)
def getWeather(): Future[Try[WeatherUpdate]] = {
ws.get("https://myweather.com/api/update") // this is all fake
.map {
case response if response.status == 200 =>
val city = (response.json \ "city").as[String]
val forecast = (response.json \ "forecast").as[Int]
Success(WeatherUpdate(city, forecast))
case response =>
Failure(new WeatherException("Could not get weather response"))
}.recover { // always recover from a future. It could throw an exception and you would never know
case ex: Exception =>
logger.error("could not get weather info", ex)
Failure(ex)
}
}
}
class WeatherException(message: String) extends RuntimeException(message: String)
在您的控制器,现在你可以使用天气更新使您的模板:
def verify(code: String): Action[AnyContent] = Action.async {
implicit request =>
weatherService.getWeather().map {
case Success(weatherUpdate) => Ok(weather_template(weatherUpdate))
case Failure(ex) => BadRequest(weather_error())
}
}