我正在评估在Scala中使用Play2mini开发一种介于移动客户端和现有web服务之间的服务的可能性。我正在寻找一个最简单的代码示例,其中Play2mini实现了服务器和客户端。理想情况下,客户将使用Akka2演员。
有了这个问题,我想知道它是如何做到的,但也想看看Play2 Mini和Akka2应该如何合作。由于Play2 Mini似乎是Akka HTTP模块的替代品。
Play2mini包含以下代码示例,我在其中创建了两个TODO。如果有人能帮我开始一些示例代码,我将非常感激。
package com.example
import com.typesafe.play.mini._
import play.api.mvc._
import play.api.mvc.Results._
object App extends Application {
def route = {
case GET(Path("/testservice")) & QueryString(qs) => Action{ request=>
println(request.body)
//TODO Take parameter and content from the request them pass it to the back-end server
//TODO Receive a response from the back-end server and pass it back as a response
Ok(<h1>Server response: String {result}</h1>).as("text/html")
}
}
}
以下是您的示例的实现。
添加以下导入:
import play.api.libs.ws.WS
import play.api.mvc.BodyParsers.parse
import scala.xml.XML
添加以下路线:
case GET(Path("/testservice")) & QueryString(qs) => Action{ request =>
Async {
val backendUrl = QueryString(qs,"target") map (_.get(0)) getOrElse("http://localhost:8080/api/token")
val tokenData = QueryString(qs,"data") map (_.get(0)) getOrElse("<auth>john</auth>")
WS.url(backendUrl).post(XML loadString tokenData).map { response =>
Ok(<html><h1>Posted to {backendUrl}</h1>
<body>
<div><p><b>Request body:</b></p>{tokenData}</div>
<div><p><b>Response body:</b></p>{response.body}</div>
</body></html>).as("text/html") }
}
}
它所做的只是将GET
请求作为POST
请求转发到后端服务。后端服务在请求参数中指定为target
,POST请求的主体在请求参数中将指定为data
(必须是有效的XML)。额外的好处是异步处理请求(因此Async
)。一旦接收到来自后端服务的响应,前端服务就会用一些显示后端服务响应的基本HTML进行响应。
如果您想使用请求主体,我建议添加以下POST
路由而不是GET
(同样,在这个实现主体中必须是有效的XML):
case POST(Path("/testservice")) & QueryString(qs) => Action(parse.tolerantXml){ request =>
Async {
val backendUrl = QueryString(qs,"target") map (_.get(0)) getOrElse("http://localhost:8080/api/token")
WS.url(backendUrl).post(request.body).map { response =>
Ok(<html><h1>Posted to {backendUrl}</h1>
<body>
<div><p><b>Request body:</b></p>{request.body}</div>
<div><p><b>Response body:</b></p>{response.body}</div>
</body></html>).as("text/html") }
}
}
正如您所看到的,对于您的HTTP网关,您可以使用Async
和play.api.libs.ws.WS
,Akka在后台提供异步处理(不需要显式的Actor)。祝你的Play2/Akka2项目好运。
romusz 的精彩回答
另一种发出(阻止)HTTP GET请求的方法:
import play.api.libs.ws.WS.WSRequestHolder
import play.api.libs.ws.WS.url
import play.api.libs.concurrent.Promise
import play.api.libs.ws.Response
val wsRequestHolder: WSRequestHolder = url("http://yourservice.com")
val promiseResponse: Promise[Response] = wsRequestHolder.get()
val response = promiseResponse.await.get
println("HTTP status code: " + response.status)
println("HTTP body: " + response.body)