How to redirect WSRsponse without explicitly matching the result

So, I have the following action, and I would like to find a way to directly return the response without tying it to the result for every possible status code. Skip the if-else part.

def testAction = Action { implicit requestIn => {

   val requestOut : WSRequest = WS.url("test-domain-name:9998")

   val queryString = requestIn.queryString.map { case (k,v) => k -> v.mkString }

   val futureResponse : Future[WSResponse] = requestOut.withQueryString(queryString.toList: _*).get()

   val response = Await.result(requestOut.withQueryString(queryString.toList: _*).get(), 5 seconds)

   if(response.status == 200) {
      Ok(response.xml)
   } else {
      BadRequest(response.body)
   }

}

      

+3


source to share


3 answers


You don't have to wait for the result. The replay framework supports asynchronous actions:

def testAction = Action.async { implicit requestIn =>

    val requestOut: WSRequest = WS.url("test-domain-name:9998")

    val queryString = requestIn.queryString.map { case (k, v) => k -> v.mkString }

    val futureResponse: Future[WSResponse] = requestOut.withQueryString(queryString.toList: _*).get()

    futureResponse

}

      

And the implicit conversion:



implicit def Response2Result(response: Future[WSResponse]): Future[Result] = {
  response map {
    response =>
      val headers = response.allHeaders map {
        h => (h._1, h._2.head)
      }
      Result(ResponseHeader(response.status, headers), Enumerator(response.body.getBytes))
  }
}

      

See the github issue .

+5


source


Changing Mon Calamari's answer for Play 2.5



implicit def Response2Result(response: Future[WSResponse]): Future[Result] = {
  response map {
    response =>
      val headers = response.allHeaders map {
        h => (h._1, h._2.head)
      }
      Result(ResponseHeader(response.status, headers), Strict(response.bodyAsBytes, None))
  }
}

      

+3


source


This is an updated answer based on Barak B.N.'s answers. and Mon Calamari for Play 2.6:

import play.api.http.HttpEntity
import play.api.libs.ws.WSResponse
import scala.concurrent.Future

def response2Result(response: Future[WSResponse]): Future[Result] = {
  response map {
    response =>
      val headers = response.headers
        .map { h => (h._1, h._2.head) }
        .filter { _._1.toLowerCase != "content-length" }
      Result(
        ResponseHeader(response.status, headers),
        HttpEntity.Strict(response.bodyAsBytes, Some(response.contentType))
      )
  }
}

      

The main differences are the replacement allHeaders

for headers

in 2.6 and the removal of the "content length" header from "Result" because the "explicit header is Content-Length

not allowed" Akka.

Also check out Discussion Discussion # 2239 and PR # 4787 .

0


source







All Articles