Comment puis-je effectuer les opérations suivantes dans Scala:
Vous pouvez essayer Dispatch . Un peu difficile à saisir au début, mais après un moment, j'ai commencé à aimer ça. Cela fonctionne sur 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 >|)
Vous pouvez simplement utiliser Java.net.URL pour envoyer des requêtes HTTP GET et HTTP POST. Vous pouvez également définir les en-têtes de requête HTTP sur la HttpURLConnection comme suit:
val con = url.openConnection.asInstanceOf[HttpURLConnection]
con.setRequestProperty("Header", "Value")
Je me suis écrit une classe utilitaire qui fait exactement cela. Tu peux le voir ici:
c’est ma propre implémentation d’un simple client Http incluant la gestion des cookies. Cela vous sera peut-être utile. Mais je ne suis pas sûr que la modification de l'en-tête soit directement possible (cela nécessitera peut-être votre propre implémentation d'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
}
}
Bien que j'apprécie la bibliothèque Dispatch pour tout ce qu'elle vaut, la syntaxe me perturbe encore un peu.
Quelqu'un m'a dirigé vers scalaj-http l'autre jour qui semble un peu plus facile
En ce qui concerne simplement obtenir des données de l'URL. Si vous ne souhaitez pas utiliser de sources externes, alors:
val in = scala.io.Source.fromURL("http://some.your.url/params?start&here",
"utf-8")
for (line <- in.getLines)
println(line)
Pour tout le reste, vous pouvez choisir la méthode de votre choix parmi les réponses ci-dessus.
Basé sur la réponse de @Antonin Brettsnajdr, une version simple du téléchargement d'un fichier à l'aide de 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(_))
Vous pouvez utiliser spray-client . La documentation fait défaut (il m'a fallu des efforts pour comprendre comment faire des requêtes GET avec des paramètres de requête ), mais c'est une excellente option si vous utilisez déjà un spray. Nous l'utilisons à AI2 over dispatch parce que les opérateurs sont moins symboliques et que nous utilisons déjà un spray/des acteurs.
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) }
J'ai utilisé Dispatch, Spray Client et la bibliothèque client Play WS ... Aucun d'entre eux n'était simplement à utiliser ou à configurer. J'ai donc créé une bibliothèque client HTTP plus simple qui vous permet d'exécuter toutes les requêtes HTTP classiques en une ligne unique.
Voir un exemple:
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)
}
... produit ...
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en-GB">...</html>
La bibliothèque s’appelle Cirrus et est disponible via Maven Central.
libraryDependencies += "com.github.godis" % "cirrus_2.11" % "1.4.1"
La documentation est disponible sur GitHub
https://github.com/Godis/Cirrus