web-dev-qa-db-fra.com

Opérations http Scala

Comment puis-je effectuer les opérations suivantes dans Scala:

  • HTTP Obtenir
  • HTTP Obtenir avec en-têtes personnalisés
  • HTTP Post
20
Omry Yadan

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 >|)
21
thoredge

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:

https://github.com/gruenewa/gruenewa-misc/blob/master/gruenewa-wsclient/src/main/scala/gruenewa/wsclient/Service.scala

18
gruenewa

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
  }
}
11

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

8
djhworld

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.

4
DenisD

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(_))
1
Hanxue

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) }
0
schmmd

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
0