Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
858 views
in Technique[技术] by (71.8m points)

scala - Basic usage of Dispatch 0.9

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).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
...