This is a fully featured http client for Scala which wraps java.net.HttpURLConnectionhtml
Features:java
Non-Features:git
Works in Google AppEngine and Android environments.github
Note: 2.x.x is a new major version which is both syntactically and behaviorally different than the 0.x.x version.json
Previous version is branched here: https://github.com/scalaj/scalaj-http/tree/0.3.xapi
Big differences:bash
libraryDependencies += "org.scalaj" %% "scalaj-http" % "2.4.1"
<dependency> <groupId>org.scalaj</groupId> <artifactId>scalaj-http_${scala.version}</artifactId> <version>2.4.1</version> </dependency>
If you're including this in some other public library. Do your users a favor and change the fully qualified name so they don't have version conflicts if they're using a different version of this library. The easiest way to do that is just to copy the source into your project :)cookie
import scalaj.http._ val response: HttpResponse[String] = Http("http://foo.com/search").param("q","monkeys").asString response.body response.code response.headers response.cookies
Http(url)
is just shorthand for a Http.apply
which returns an immutable instance of HttpRequest
.
You can create a HttpRequest
and reuse it:oracle
val request: HttpRequest = Http("http://date.jsontest.com/") val responseOne = request.asString val responseTwo = request.asString
All the "modification" methods of a HttpRequest
are actually returning a new instance. The param(s), option(s), header(s) methods always add to their respective sets. So calling .headers(newHeaders)
will return a HttpRequest
instance that has newHeaders
appended to the previous req.headers
app
Http("http://foo.com/add").postForm(Seq("name" -> "jon", "age" -> "29")).asString
Note: the .oauth(...)
call must be the last method called in the request construction
import scalaj.http.{Http, Token} val consumer = Token("key", "secret") val response = Http("https://api.twitter.com/oauth/request_token").postForm(Seq("oauth_callback" -> "oob")) .oauth(consumer).asToken println("Go to https://api.twitter.com/oauth/authorize?oauth_token=" + response.body.key) val verifier = Console.readLine("Enter verifier: ").trim val accessToken = Http("https://api.twitter.com/oauth/access_token").postForm. .oauth(consumer, response.body, verifier).asToken println(Http("https://api.twitter.com/1.1/account/settings.json").oauth(consumer, accessToken.body).asString)
Http("http://foo.com").{asString, asBytes, asParams}
Those methods will return an HttpResponse[String | Array[Byte] | Seq[(String, String)]]
respectively
val response: HttpResponse[Map[String,String]] = Http("http://foo.com").execute(parser = {inputStream =>
Json.parse[Map[String,String]](inputStream)
})
Http(url).postData(data).header("content-type", "application/json").asString.code
Http(url).postMulti(MultiPart("photo", "headshot.png", "image/png", fileBytes)).asString
You can also stream uploads and get a callback on progress:
Http(url).postMulti(MultiPart("photo", "headshot.png", "image/png", inputStream, bytesInStream, lenWritten => { println(s"Wrote $lenWritten bytes out of $bytesInStream total for headshot.png") })).asString
Http("http://httpbin.org/stream/20").execute(is => {
scala.io.Source.fromInputStream(is).getLines().foreach(println)
})
note that you may have to wrap in a while loop and set a long readTimeout to stay connected
Http("https://localhost/").option(HttpOptions.allowUnsafeSSL).asString
Http(url).method("HEAD").asString
These are set to 1000 and 5000 milliseconds respectively by default
Http(url).timeout(connTimeoutMs = 1000, readTimeoutMs = 5000).asString
val response = Http(url).proxy(proxyHost, proxyPort).asString
The .option()
method takes a function of type HttpURLConnection => Unit
so you can manipulate the connection in whatever way you want before the request executes.
By default, the charset for all param encoding and string response parsing is UTF-8. You can override with charset of your choice:
Http(url).charset("ISO-8859-1").asString
You don't have to use the default Http singleton. Create your own:
object MyHttp extends BaseHttp ( proxyConfig = None, options = HttpConstants.defaultOptions, charset = HttpConstants.utf8, sendBufferSize = 4096, userAgent = "scalaj-http/1.0", compress = true )
Access-Control, Content-Length, Content-Transfer-Encoding, Host, Keep-Alive, Origin, Trailer, Transfer-Encoding, Upgrade, Via
headersSome of the headers are locked by the java library for "security" reasons and the behavior is that the library will just silently fail to set them. You can workaround by doing one of the following:
-Dsun.net.http.allowRestrictedHeaders=true
System.setProperty("sun.net.http.allowRestrictedHeaders", "true")
以上官方說明,下面具體怎麼使用:
首先Http請求,返回json類型數據,就要有json解析及轉化工具。
Scala sbt引入scalaj-http及spray-json.
"org.scalaj" % "scalaj-http_2.12" % "2.3.0", "com.github.wangzaixiang" %% "spray-json" % "1.3.4", "com.google.code.gson" % "gson" % "2.7"
工具類以下:
package test.scalajhttp import com.google.gson.Gson import scalaj.http.{Http, HttpOptions, HttpResponse} import spray.json.DefaultJsonProtocol._ import spray.json.{JsValue, _} /** * 類功能描述:Scalaj http 工具類 * * @author WangXueXing create at 19-8-15 下午5:56 * @version 1.0.0 */ object ScalajHttpUtil { /** * 成功 */ val STATUS_SUCCESS: String = "success" /** * 失敗 */ val STATUS_FAIL: String = "fail" /** * http公共請求類 * * @param url Http路徑如:https://www.baidu.com * @param params 參數 * @return */ def requestUrl(url: String, params: Map[String, String]) = { val httpRequest = Http(url) .header("Content-Type", "application/xml")//"application/json" .header("Charset", "UTF-8") .option(HttpOptions.readTimeout(10000)) val response: HttpResponse[String] = (params != null && !params.isEmpty) match { case true => httpRequest.params(params).asString case false => httpRequest.asString } response.body } /** * http公共請求類 * * @param url Http路徑如:https://www.baidu.com * @param requestJson Json參數 * @return */ def postRequestUrl(url: String, requestJson: String) = { val httpRequest = Http(url) .header("Content-Type", "application/xml")//"application/json" .header("Charset", "UTF-8") .option(HttpOptions.readTimeout(10000)) val response: HttpResponse[String] = (requestJson != null && !requestJson.isEmpty) match { case true => httpRequest.postData(requestJson).asString case false => httpRequest.asString } response.body } /** * 將object映射json string * * @param obj * @return */ def objToJson(obj: NcRespose): String = { new Gson().toJson(obj) } /** * 將map數據映射到Object * * @param jsonStr * @return */ def jsonToObject(jsonStr: String): NcRespose = { val jsonObj = jsonStr.parseJson.convertTo[Map[String, JsValue]] mapToObject(jsonObj) } /** * 將map數據映射到PRackType類上 * * @param jsonMap * @return */ def mapToJson(jsonMap: Map[String, JsValue]): String = { val obj = mapToObject(jsonMap) new Gson().toJson(obj) } /** * 將map數據映射到Object * * @param jsonObj * @return */ def mapToObject(jsonObj: Map[String, JsValue]): NcRespose = { NcRespose( status = toStringValue(jsonObj.get("status").get), message = toStringValue(jsonObj.get("message").get) ) } def toStringValue(jsValue: JsValue): String = { s"$jsValue".replace("\"", "") } def toIntValue(jsValue: JsValue): Int = { s"$jsValue".replace("\"", "").toInt } def toLongValue(jsValue: JsValue): Long = { s"$jsValue".replace("\"", "").toLong } def main(args: Array[String]): Unit = { val jsonStr1 = "{\"billhead\":{\"bill_date\":\"2019-08-13\",\"creationtime\":\"2019-08-13 17:55:00\",\"creator\":\"1000\",\"local_money\":100,\"local_rate\":1,\"objecttype\":0,\"payway\":0,\"pk_currtype\":\"CNY\",\"pk_org\":\"101\",\"primal_money\":100},\"items\":[{\"billdetail_no\":0,\"pay_local\":100,\"pay_primal\":100,\"pk_oppaccount\":\"421860158018800081218\"}]}" val jsonStr = postRequestUrl("http://10.100.99.98:8000/uapws/rest/SyncCMPPayBillRestful/add", jsonStr1) val gson = new Gson() val respose = gson.fromJson(jsonStr, classOf[NcRespose]) // val respose = jsonToObject(jsonStr) // println(jsonStr) if(respose.status == STATUS_SUCCESS){ println(s"success: ${respose.message}") } else { println(s"fail: ${respose.message}") } } }
case class NcRespose(status: String, message: String)
scala中使用json,比java中使用json複雜一些。嘗試了json-smart;fast json; gson;json4s以及scala自帶的json。
總結以下:
1. 普通json string 轉化 object, 使用JSON.pareseFull 。
JSON.parseFull(str).get.asInstanceOf[Map[String, String]]("key")
2. json 與 map 互相轉化
val colors:Map[String,Object] = Map("red" -> "123456", "azure" -> "789789") val json = JSONObject(colors) println(json) val jsonMap = JSON.parseFull(json.toString).get.asInstanceOf[Map[String,Object]] println(jsonMap)
3. json 與 class 互相轉化
case class Student( name:String , no: String ) val gson = new Gson val student = Student("張三", "100") val str = gson.toJson(student, classOf[Student]) println(str) val student2 = gson.fromJson(str, classOf[Student]) println(student2)
尤爲注意:使用 classOf ,不能使用 getclass
4. json與Map互相轉化,需使用java的map
val map = new util.HashMap[String, Object]() map.put("abc", List(s1,s2).toArray) val gson = new Gson() println( gson.toJson(map) ) 另附,json判斷代碼 def isGoodJson(json: String):Boolean = { if(null == json) { return false } val result = JSON.parseFull(json) match { case Some(_: Map[String, Any]) => true case None => false case _ => false } result }
請參考: