Play WS ist eine leistungsstarke HTTP -Client -Bibliothek, die ursprünglich vom Play -Team für die Verwendung mit Play Framework entwickelt wurde. Es verwendet AsynchtTPClient für die HTTP -Client -Funktionalität und hat keine Spielabhängigkeiten.
Wir haben hier einige Unterlagen zur Verwendung von Play WS in Ihrer App (ohne Spiel) zur Verfügung gestellt. Weitere Informationen zur Verwendung von Play WS im Spiel finden Sie in der Play -Dokumentation.
Um loszulegen, können Sie play-ahc-ws-standalone
als Abhängigkeit von SBT hinzufügen:
LibraryDependenzen += "org.playframework" %% "Play-AHC-WS-Standalone" % "neuest_version" // vor Version 3.0.0: LibraryDependenzen += "com.typesafe.play" %% "Play-AHC-WS- eigenständig " %" neuest_version "
Wo Sie LATEST_VERSION
durch die in diesem Bild gezeigte Version ersetzen :.
Dies fügt die eigenständige Version von Play WS hinzu, die von Asynchttpclient unterstützt wird. Diese Bibliothek enthält sowohl die Scala als auch die Java -APIs unter play.api.libs.ws
und play.libs.ws
Fügen Sie Folgendes hinzu:
Bibliotheksabendenzen += "org.playframework" %% "Play-WS-Standalone-XML" % PlaywSstandaloneversion LibraryDependenzen += "org.playframework" %% "Play-WSS-Standalone-Json" % PlaywStandaloneversion // vor Version 3.0.0: Bibliotheksanpendenzen += "com.typesafe.play" %% "Play-Ws-Standalone-XML" % PlaywSstandaloneVersion Bibliotheksabendenzen += "com.typesafe.play" %% "Play-WS-Standalone-Json" % PlaywSstandaloneversion
Play WS verwendet schattierte Versionen von Asynchttpclient und OAuth Signpost, die unter dem play.shaded.ahc
und play.shaded.oauth
Paketnamen neu verpackt wurden. Das Schattieren von Asynchttpclient bedeutet, dass die Version von Netty, die hinter Asynchttpclient verwendet wird, völlig unabhängig von der Anwendung ist und insgesamt das Spiel ist.
Insbesondere bedeutet das Schattieren von Asynchttpclient, dass keine Versionskonflikte zwischen Netty 4.0 und Netty 4.1 unter Verwendung von Play WS eingeführt werden.
HINWEIS :
~/.ivy2/cache
Sie mitsbt publishLocal
~/.ivy2/local
Play-Ws entwickeln undshaded-asynchttpclient
undshaded-oauth
veröffentlichen, müssen Sie sich darüber im Klaren sein Ihr aktualisierter schattierter Code, bis Sie ihn aus dem Cache entfernen. Weitere Informationen finden Sie unter http://eed3si9n.com/fieldtest. Dieser Fehler wurde als SBT/SBT#2687 eingereicht.
Da WS Shades asynchttpclient abspielen, sind die Standardeinstellungen ebenfalls schattiert und halten sich daher nicht an die AHC -Dokumentation. Dies bedeutet, dass die Einstellungen in ahc-default.properties
und die Eigenschaften der asynchttpclient-Systeme mit play.shaded.ahc
vorbereitet werden. Zum Beispiel wird die Einstellung usePooledMemory
in der schattierten Version von Asynchttpclient so definiert:
Play.shaded.ahc.org.asynchttpclient.USepooledMemory = true
Das Typsystem in Play-Ws hat sich so geändert, dass der Anforderungskörper und der Antwortkörper reichere Typen verwenden können.
Sie können Ihr eigenes Bodywritable oder BodyReadable definieren. Wenn Sie jedoch die Standardeinstellungen aus den Box -Einstellungen verwenden möchten, können Sie die Typ -Zuordnungen mit den StandardBodyReadables / StandardBodyWritables importieren.
Play.api.libs.ws.defaultBodyReadables._import Play.api.libs.ws.defaultBodyWritables.___Imports.______SPIALTICE, importieren.
Wahrscheinlich möchten Sie die XML- und JSON -Unterstützung:
Play.api.libs.ws.xmlbodyReadables._import Play.api.libs.ws.xmlbodywritables.__import
oder
importieren.api.libs.ws.jsonbodyReadables._import Play.api.libs.ws.jsonbodywritables._
Um ein Bodyreadable in einer Antwort zu verwenden, müssen Sie die Antwort explizit eingeben:
scala.concurrent importieren {executioncontext, future} importieren play.api.libs.ws.Standalonewsclientimport Play.api.libs.ws.xmlbodyReadables._ // forderdedef handlexml (ws: standalonewsclient) (implizit ec: excisionContext: future [scala [scala [scala [scala .xml.elem] = ws.url ("..."). get (). map {response => response.body [scala.xml.elem] }
oder mit Play-Json:
import Scala.Concurrent. {executionContext, Future} importieren play.api.libs.json.jsvalueImaPort Play.api.libs.ws.Standalonewsclientimport Play.api.libs.ws.jsonBodyReadables._ // forderteDef HandleJsonresp (WS: standalonewscl) (standalonewscl. implizite EC: ExecutionContext): Future [jsValue] = ws.url ("..."). get (). map {response => response.body [jsValue] }
Beachten Sie, dass es einen Sonderfall gibt: Wenn Sie die Antwort streamen, sollten Sie den Körper als Quelle erhalten:
scala.concurrent.executionContextimport org.apache.pekko.util.ByTestringimport org.apache.pekko.stream.scaladsl.Sourceimer Play.api.libs.ws.StandalonewsclientDef Usewsstream (WS: standalonewscl.) (WS: standalonewscl.) (ImplictalDewsstream (WS: Standalonewscl.) (ImplictalDewsstream (WS: standalonewscl) (standalonewscl. Ws.Url ("..."). Stream (). MAP {response => val Quelle: Quelle [Bytestring, _] = reaktion.bodyAsAsArce val _ = source // etwas mit Quelle tun }
Um zu veröffentlichen, sollten Sie in einem Typ, der eine implizite Klassenzuordnung von Bodywritable hat, übergeben:
importieren scala.concurrent.executionContextimport play.api.libs.ws.defaultbodywritables._ // forderndef postExampring (WS: Play.api.libs.ws.Standalonewsclient) (implizit EC: ExecutionContext) = {val StringData = "Helly World" ws.url ("..."). post (stringData) .map {response => / * etwas * /} machen }
Sie können auch Ihr eigenes Bodyreadable definieren:
importieren.api.libs.ws.bodyreadableImimport Play.api.libs.ws.ahc.standaloneahcwsresponsecase Class Foo (Körper: String) Implizites Val foobodyreadable = BodyReadable [foo] {reaktion => import Play.shaded.ahc.org.asynchttpclient. {response => ahcresponse} val ahcresponse = response.asinstanceof [standaloneahcwsresponse] .Wering [ahcresponse] foo (ahcresponse.getRespondeBody) }
oder Custom Bodywritable:
import org.apache.pekko.util.byTestringimport play.api.libs.ws. {bodywritable, InmemoryBody} implizit Val Writableof_foo: Bodywritable [foo] = {// https://tools -3.2 Bodywritable (foo => InmemoryBody (byTestring.fromstring (foo.tostring)), "application/vnd.company.category+foo")) }
Um die Standard -Mappings in Java zu verwenden, sollten Sie Folgendes verwenden:
Play.libs.ws.defaultBodyReadables; importieren.libs.ws.defaultBodyWritables;
gefolgt von:
öffentliche Klasse Myclient Implements DefaultBodyWritables, defaultBodyReadables {public CompletionStage <string> dostuff () {return client.url ("http://example.com") .post ("Hello World"). Dann Apply (Antwort -> Antwort .body (String ()) ); } }
Beachten Sie, dass es einen Sonderfall gibt: Wenn Sie einen Stream verwenden, sollten Sie den Körper als Quelle erhalten:
Klasse Myclass {public CompletionStage <Quelle <byTestring, nicht verwendet ); } }
Sie können auch eine Quelle veröffentlichen:
Klasse MyClass {public CompletionStage <String> dostuff () {Source <byTestring, nicht verwendet> source = from source (); return ws.url (url) .post (body (Quelle)). Dann Apply (Antwort -> Antwort.body () () ); } }
Sie können einen benutzerdefinierten BodyReadable
definieren:
Import Play.libs.ws.ahc. Getundering (); return foo.serialize (ahcresponse.getResponseBody (StandardCharets.utf_8)); } }
Sie können auch Ihr eigenes BodyWritable
definieren:
public class myclient {private bodywritable <string> Einthermethod (String String) {org.apache.pekko.util.ByTestring byTestring = org.apache.pekko.util.ByTestring.fromstring (String); Neue StandardbodyWritables.inMemoryBodyWrable (Bytestring, "Text/Plain") zurückgeben; } }
Der eigenständige Client benötigt Pekko, um Streaming -Daten intern zu verarbeiten:
In Scala rufen Sie in Scala einen Webdienst an und schließen den Kunden ab:
Paket PlaywsClientImport org.apache.pekko.actor.actorSystemimport org.apache.pekko.stream._import Play.api.libs.ws._import Play.api.libs.ws.ahc._import scala.concurent.futureObject scalaclient {{{{{{oder _ import scala.concurrent.executioncontext.implicits._ Def Main (args: array [string]): unit = {// Pekko -System für Thread- und Streaming -Management -Management -Val System = ActorSystem () erstellen System.registerOntermination {System.exit (0) } implizite val materializer = systemmaterializer (System) .Materializer // Erstellen Sie den eigenständigen WS -Client // Keine Argument -Standardeinstellungen zu einem AHCWSCLIENTCONFIG, erstellt aus // "ahcwsclientConFigfactory.forconfig (configFactory.load, this.getClass.getClassesader)" val WSclient = standalonahcwsclasslader) "val WSclient = standalonahcwsclasslader)" val Wsclient = standalonahcwsclasslader) "val Wsclient = standalonahcwsclasses. () Rufen Sie an (WSClient) .Andhen {case _ => wsclient.close ()} .Andhen {case _ => system.terminate ()} } def Call (WSCLIENT: StandaloneWSClient): Future [Einheit] = {{ wsclient.url ("http://www.google.com") .get (). map {response => VAL statusext: String = response.Statusext val body = response.body [String] println (s "erhalten eine Antwort $ Statusext: $ body") } } }
Sie können den eigenständigen Client auch direkt aus einer Asynchttpclient -Instanz erstellen:
Object ScalaClient {def main (Args: Array [String]): Einheit = {// verwenden importieren.shaded.ahc.org.asynchttpclient._val asynchttpclientConfig = new DefaultAsynchttpclientconfig.builder () .SetMaxRequestretry (0) .Setshutdownquietperiod (0) .setShutdowntimeout (0) .buildval asynchttpclient = new DefaultAsynchttpclient (asynchttpclientConfig) val wsclient = new standaloneahcwsclient (asynchttpclient) // ... } }
Dies ist nützlich, wenn es eine AsynChTPClient -Konfigurationsoption gibt, die in der WS -Konfigurationsschicht nicht verfügbar ist.
In Java ist die API ähnlich wie folgt:
Paket PlaywsClient; import org.apache.pekko.actor.actorSystem; import org.apache.pekko.stream. ahc.*; öffentliche Klasse JavaClient Implements DefaultBodyReadables {private endgültige StandaloneAhcwsclient Client; privates endgültiges ActorSystem -System; public static void main (String [] args) {// PEKKO Materiators einrichten, um Streamingfinal String Name = "WSClient"; Actorsystem.create (name); System.registerOntermination (() -> system.exit (0)); materializer materializer = systemmaterializer.get (System) .materializer (); // Erstellen Sie den WS -Client aus der `application.conf` Datei, der aktuelle Klassenloader und Materializer. Javaclient.run (); } JavaClient (Actorsystem -System, standaloneahcwsclient client) {this.System = System; this.client = client; } public void run () {client.url ("http://www.google.com") .get () .Wencomplete ((Antwort, Throwable) -> {String StatuseText = Antwort.GetStatUntext (); String body = response.getBody (string ()); System.out.println ("Got a response" + StatuStext); }) .thenrun (() -> {try {client.close (); } catch (Ausnahme e) {e.printstacktrace (); } }) .thenrun (System :: Termin); } }
Ebenso können Sie den AsynChTTPClient -Client ausdrücklich aus der Konfiguration bereitstellen:
öffentliche Klasse JavaClient Implements DefaultBodyReadables {public static void main (String [] args) {// ... // assynchttpclient direkt von configaSynChtpclientConfig asynChttpclientConfig = new DefaultAsynChttpclientConfig.builder () () () () () () () .SetMaxRequestretry (0) .Setshutdownquietperiod (0) .setshutdowntimeout (0) .build (); asynchttpclient asynchttpclient = new DefaultAsynchttpclient (asynchttpclientConfig); // WSClient -Instanz direkt von asynchttpclient.wsclient client = new ahcwsclient (asynchttpclient, Materializer); // ...} einrichten }
Spielen Sie WS implementiert HTTP Caching durch Cachingasynchttpclient, Ahchttpcache und CacheControl, eine minimale HTTP -Cache -Management -Bibliothek in Scala.
Um einen eigenständigen AHC -Client zu erstellen, der Caching verwendet, geben Sie in einer Instanz von Ahchttpcache mit einem Cache -Adapter an die zugrunde liegende Implementierung weiter. Zum Beispiel können Sie Folgendes verwenden, um Koffein als zugrunde liegende Cache zu verwenden:
import scala.concurrent.futureimport java.util.concurrent Cache. {ahchttpcache, cache, effektivurikey, responseEntry} Klasse caffeinehttpcache erweitert Cache {val liegende = Coffein.Newbuilder ()) .Ticker (Ticker.SystemTicker ()) .exprea.TerWrite (365, TimeUnit.Days) .build [effektivurikey, responseEnterry] () def entfernen (Schlüssel: effektivurikey) = Future.successful (Option (zugrunde liegende. (Schlüssel, Eintrag)) Def GET (Schlüssel: effektivurikey) = Future.successful } Def Withcache (implizit m: org.apache.pekko.stream.materializer): standaloneahcwsclient = {implizit def ec = m.executionContext val cache = new CaffeinHttpcache () standaloneahcwsclient (httpcache = einige (newchchttpcache }
Es gibt eine Reihe von Leitfäden, die beim Zusammenstellen von Cache-Kontroll-Headern helfen:
Mozillas Anleitung zum HTTP -Caching
Mark Nottinghams Leitfaden zum Caching
Http Caching
Ruhe einfach: HTTP -Cache
Siehe https://github.com/playframework/.github/blob/main/releassing.md
Play WS ist unter der Apache -Lizenz, Version 2, lizenziert. Weitere Informationen finden Sie in der Lizenzdatei.