Question

I want to POST to a URL, setting query parameters and headers and passing a raw string in the body. I then want to do the request and get the output string, so that i can convert it to JSON. I also want exception handling to respond to different kinds of errors (and handle redirects)

But Dispatch 0.9 is badly documented, breaks API with documented versions and is very quirky, so I cannot come up with a complete solution. I am utterly stuck, hence I ask for a lot.


This is all I can come up with, but setting the query params is weird:

val solr = host("localhost", 8983)
val req  = solr / "update" / "json" 
    setQueryParameters( Map( "commit" -> "true")) 
    setHeader( "Content-type", "application/json")
    setBody( a)

But setting the query parameters gives me a tough error:

<console>:14: error: type mismatch;
 found   : scala.collection.immutable.Map[java.lang.String,java.lang.String]
 required: com.ning.http.client.FluentStringsMap
       val req  = solr / "update" / "json"  setQueryParameters( Map( "commit" -> "true"))

Please help with setting the request completely: HTTPS, redirects, query parameters, headers and the POST method.

Also help with (synchronously, I want it that way) executing the request to get the body (and headers) and branching depending on the response code (200, 301, 302, 400, 500).

Was it helpful?

Solution

You're not too far off. The following should work for your request definition:

import dispatch._

val params = Map("commit" -> "true")
val headers = Map("Content-type" -> "application/json")

val solr = host("localhost", 8983)

val req = solr / "update" / "json" << a <<? params <:< headers

Or, less operatory-ily:

val req = url("http://localhost:8983/update/json").POST
  .setBody(a)
  .addQueryParameter("commit", "true")
  .addHeader("Content-type", "application/json")

Throw a .secure in there somewhere if you want to use HTTPS.

You can get a promise (which essentially represents the result of a deferred request operation) like this:

val result = Http(req OK as.String).either

And then use it like this, for example:

result() match {
  case Right(content)         => println("Content: " + content)
  case Left(StatusCode(404))  => println("Not found")
  case Left(StatusCode(code)) => println("Some other code: " + code.toString)
}

While I agree that the 0.9 documentation is sparse in some places, it does provide a very useful explanation of how to handle asynchronous request operations with promises.


OP's addition: this bit completes this answer for me. This gets the response in a simple, blocking way.

val response = Http(req)()
val body response.getResponseBody

OTHER TIPS

I use a POST in my simple use case of Dispatch 0.9.1, which I setup as follows:

val SERVICES_URL = "http://myhost/mycontext"

val postFields: Map[String, String] = ...
val request = url(SERVICES_URL) << postFields OK as.String
val post = Http(request)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top