Как выполнить следующее в Scala:
- HTTP Get
- HTTP Get С пользовательскими заголовками
- Сообщение HTTP
Как выполнить следующее в Scala:
Вы можете попробовать Dispatch. Сначала трудно понять, но через некоторое время мне это стало нравиться. Он работает поверх HttpClient.
import dispatch.Http
import Http._
// Get
Http(url("http://youruri.com/yo") >>> System.out)
// Get with header
Http(url("http://youruri.com/yo") <:< Map("Accept" -> "application/json") >>> System.out)
// Post
Http(url("http://youruri.com/yo") << yourPostData >|)
Вы можете просто использовать java.net.URL для отправки запросов HTTP GET и HTTP POST. Вы также можете установить заголовки HTTP-запросов в HttpURLConnection следующим образом:
val con = url.openConnection.asInstanceOf[HttpURLConnection]
con.setRequestProperty("Header", "Value")
Я написал себе класс утилиты, который делает именно это. Вы можете увидеть это здесь:
это моя собственная реализация простого Http-клиента, включая управление файлами cookie. Может быть, это будет полезно для вас. Но я не уверен, что возможно изменение заголовка (это может потребовать вашей собственной реализации URLConnection).
import java.io.OutputStreamWriter
import java.net.{URLConnection, URL}
class Http(userAgent: String,
encoding: String,
HttpRequestTimeout: Int = 15000) {
import collection.JavaConversions._
import Implicits.wrapInputStream
import java.net.URLEncoder.encode
var cookies = Map[String, String]()
private def loadCookies(conn: URLConnection) {
for ((name, value) <- cookies) conn.setRequestProperty("Cookie", name + "=" + value)
}
private def saveCookies(conn: URLConnection) {
conn.getHeaderFields.lift("Set-Cookie") match {
case Some(cList) => cList foreach { c =>
val (name,value) = c span { _ != '=' }
cookies += name -> (value drop 1)
}
case None =>
}
}
private def encodePostData(data: Map[String, String]) =
(for ((name, value) <- data) yield encode(name, encoding) + "=" + encode(value, encoding)).mkString("&")
def Get(url: String) = {
val u = new URL(url)
val conn = u.openConnection()
conn.setRequestProperty("User-Agent", userAgent)
conn.setConnectTimeout(HttpRequestTimeout)
loadCookies(conn)
conn.connect
saveCookies(conn)
conn.getInputStream.mkString
}
def Post(url: String, data: Map[String, String]) = {
val u = new URL(url)
val conn = u.openConnection
conn.setRequestProperty("User-Agent", userAgent)
conn.setConnectTimeout(HttpRequestTimeout)
loadCookies(conn)
conn.setDoOutput(true)
conn.connect
val wr = new OutputStreamWriter(conn.getOutputStream())
wr.write(encodePostData(data))
wr.flush
wr.close
saveCookies(conn)
conn.getInputStream.mkString
}
}
Хотя я ценю библиотеку Dispatch за все, что стоит, синтаксис меня все еще немного смущает.
Кто-то направил меня на scalaj-http на днях, который кажется немного проще
Относительно просто GETting данных из URL. Если вы не хотите использовать внешние источники, то:
val in = scala.io.Source.fromURL("http://some.your.url/params?start&here",
"utf-8")
for (line <- in.getLines)
println(line)
Для всех остальных вещей вы можете выбрать любой метод, который вам нравится из приведенных выше ответов.
Основываясь на ответе @Antonin Brettsnajdr, просто версия загрузки файла с помощью POST
val conn = new URL("http://myserver.appspot.com/upload").openConnection()
conn.setDoOutput(true)
conn.connect
val input = new FileInputStream(file)
val buffer = new Array[Byte](2 * 1024 * 1024)
Stream.continually(input.read(buffer)).takeWhile(_ != 1).foreach(conn.getOutputStream.write(_))
Вы можете использовать spray-client. Документации не хватает (мне потребовалось некоторое копание, чтобы узнать как делать запросы GET с параметрами запроса), но это отличный вариант, если вы уже используете спрей. Мы используем его в AI2 над dispatch потому что операторы менее символичны, и мы уже используем спрей/актеров.
import spray.client.pipelining._
val url = "http://youruri.com/yo"
val pipeline: HttpRequest => Future[HttpResponse] = addHeader("X-My-Special-Header", "fancy-value") ~ sendReceive
// Get with header
pipeline(Get(url)) map (_.entity.asString) onSuccess { case msg => println(msg) }
// Get with header and parameters
pipeline(Get(Uri(url) withParams ("param" -> paramValue)) map (_.entity.asString) onSuccess { case msg => println(msg) }
// Post with header
pipeline(Post(url, yourPostData)) map (_.entity.asString) onSuccess { case msg => println(msg) }
Я использовал Dispatch, Spray Client и клиентскую библиотеку Play WS... Ни один из них просто не использовался или не настраивался. Поэтому я создал более простую библиотеку HTTP-клиента, которая позволяет выполнять все классические HTTP-запросы в простых однострочных.
См. пример:
import cirrus.clients.BasicHTTP.GET
import scala.concurrent.Await
import scala.concurrent.duration._
object MinimalExample extends App {
val html = Await.result(Cirrus(GET("https://www.google.co.uk")), 3 seconds)
println(html)
}
... производит...
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en-GB">...</html>
Библиотека называется Cirrus и доступна через Maven Central
libraryDependencies += "com.github.godis" % "cirrus_2.11" % "1.4.1"
Документация доступна на GitHub
https://github.com/Godis/Cirrus