2012-02-13 1 views
8

Я оцениваю возможность использования Play2-mini с помощью Scala для разработки службы, которая будет размещаться между мобильным клиентом и существующей веб-службой. Я ищу простейший пример кода, в котором Play2-mini реализует сервер и клиент. В идеале клиент будет использовать акка2 актеров.Play2-mini и Akka2 для HTTP-шлюза

С этим вопросом я пытаюсь выяснить, как это делается, но и посмотреть, как должны взаимодействовать Play2-Mini и Akka2. Поскольку Play2-Mini является заменой для модулей Akka HTTP.

Play2-mini содержит следующий пример кода, в котором я создал два 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") 
    } 
    } 
} 
+0

Позволь мне знать, если мой ответ не то, что вы ожидали, и нуждается в некоторых изменениях. Или уточните, пропустил ли я это. Возможно, вы подумали, что вам нужно явно использовать участников для вашего HTTP-шлюза, но это не так. Самый простой способ - использовать «Async» и «play.api.libs.ws.WS» и позволить Play framework управлять акками Akka. – romusz

+0

Спасибо за дружескую помощь @romusz. Ответ выглядит безупречно ;-), но у меня не было возможности реализовать его на моем сервере, поэтому мой ответ был немного вялым. Что-то еще приземлилось на моем столе, но я доберусь до него в течение следующих двух-двух дней. Еще раз спасибо. – Jack

+0

Рад, что я мог помочь. – romusz

ответ

7

Реализация вашего примера.

Добавьте следующий импорт:

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 запроса на серверную Serivce как POST запроса. Внутренняя служба указывается в параметре запроса как target, а тело запроса POST указывается в параметре запроса как data (должно быть допустимым XML). В качестве бонуса запрос обрабатывается асинхронно (следовательно, Async). После того, как получен ответ от внутренней службы, передняя служба отвечает некоторым базовым HTML-кодом, отображающим ответ службы back-end.

Если вы хотите использовать тело запроса, я хотел бы предложить добавить следующий 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 под капотом, работающим для обеспечения асинхронной обработки (без явного участия Актеров). Удачи вам в вашем проекте Play2/Akka2.

+0

Хороший ответ, спасибо. – Jack

1

Великий ответ на 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)