[2.2-Scala] Future how to print out Response (plain/text)?

676 views
Skip to first unread message

Justin Maat

unread,
Apr 24, 2014, 12:42:27 PM4/24/14
to play-fr...@googlegroups.com
Hi all,

I'm pretty new to Scala and Play, so sorry if this is a dumb question.  I'm trying to call a webservice and print out the entire response to the console but can't seem to figure it out.  The response should be coming back as plain/text and all the examples I've seen are for examples to validate JSON that's been serialized back into an object.

My code (note this is inside a junit test): 

    val holder : WSRequestHolder = WS.url("http://mydomain.com/")
    val futureResponse
: Future[Response] = holder.get()


How exactly can I read the response back and print out the full text?  I've seen ways use .map on the Response objects, but I'm still a bit confused.


One method i've tried, but not sure where to put the println statement.  In this case, I know the webservice returns back a plain/text so I've used String with the Future

    val futureResult: Future[String] = WS.url("http://mydomain/").get().map {
      response
=>
        response
.xml.text   //should this be response.body?  How can I print this out?
   
}




In java, I would normally use something like JaxRS to get the response as an InputStream, load it into a String, then print that out.  I'm not sure if that's the best method in Scala, or if there's an easier way.


I feel like I've overlooked something simple.  Any ideas?




Justin Maat

unread,
Apr 24, 2014, 1:53:07 PM4/24/14
to play-fr...@googlegroups.com

So, apparently I missed the entire section on the api  scala.concurrent.Await

Also, I found the correct way to get the full body text was response.body

Sorry, not sure how I missed these.  The full implementation below..

    val futureResult: Future[String] = WS.url("http://mydomain.com").get().map {
      response
=>
        response
.body
   
}


   
//arbitrary 5 seconds
    val result
= Await.result(futureResult, 5 seconds)


    println
(result)  




Ryan Tanner

unread,
Apr 24, 2014, 2:11:49 PM4/24/14
to play-fr...@googlegroups.com
You really shouldn't use Await, you're just setting yourself up for performance problems down the road.  Your first example would've worked find if you replaced "response.xml.text" with "println(response.body)"
Message has been deleted

Justin Maat

unread,
Apr 24, 2014, 3:31:31 PM4/24/14
to play-fr...@googlegroups.com
Hi Ryan,

Thanks for your suggestion on avoiding Await.  I'll take a look into it more.

But I don't quite follow the idea to replace response.xml.text  with println(response.body).  I'm returning a Future[String] , so I don't think I can just print out the statement in that block (unless I'm missing something?) 

For example 
    val futureResult: Future[String] = WS.url("http://mydomain.com/").get().map {
      response
=>
        println
(response.body)    //compile error bc it's not returning a String
   
}



I also tried using a callback, but couldn't quite figure out the correct code.
    val futureResult = WS.url("http://mydomain.com/").get().map {
      response
=>
        response
.body
   
}
   
   
//would this work?  if so, what would I put here?
    futureResult
.onSuccess{
     
return println("successful")  //this prints, but I can't figure out how to get the body in here
   
}


Christopher Hunt

unread,
Apr 24, 2014, 7:02:49 PM4/24/14
to play-fr...@googlegroups.com
Treat Await as a code smell. :-)

Justin Maat

unread,
Apr 24, 2014, 8:21:18 PM4/24/14
to play-fr...@googlegroups.com
Ok, thanks for the tip, this makes sense actually.  I still have more to read; but if I'm understanding correctly Await will actually block execution until it completes or the duration time is met (in my example above, 5 seconds).

So, I've tried the code below but it still won't work.  The reason looks to be that the execution is completing before the Webservice Result has a chance to send the data back.  This would make sense since I'm running this code block from a junit test method.  In my controllers and/or other code, this won't be an issue since the web app will always be running.

    val futureResult: Future[String] = WS.url("http://mydomain.com/").get().map {
      response
=>

        response
.body
   
}
     
    futureResult onComplete
{
     
case Success(body) => return println(body)
     
case Failure(error) => return println(error)
   
}


When I try adding a Thread.sleep() , I can get the printout to occur successfully (similar to Await), but this is obviously blocking the thread as well.  

    val futureResult: Future[String] = WS.url(myurl).get().map {
      response
=>
        response
.body
   
}
     
    futureResult onComplete
{
     
case Success(body) => return println(body) //prints successfully now, bc it has up to 1 sec to run the above
     
case Failure(error) => return println(error)
   
}
   
   
Thread.sleep(1000)


Looks like I have some learning todo on how to properly test asynchronous logic in Junit :)

Thanks for the help!
Reply all
Reply to author
Forward
0 new messages