Play WS adalah perpustakaan klien HTTP yang kuat, yang awalnya dikembangkan oleh tim bermain untuk digunakan dengan kerangka kerja bermain. Ini menggunakan asynchttpClient untuk fungsionalitas klien HTTP dan tidak memiliki ketergantungan bermain.
Kami telah memberikan beberapa dokumentasi di sini tentang cara menggunakan Play WS di aplikasi Anda (tanpa bermain). Untuk informasi lebih lanjut tentang cara menggunakan Play WS di Play, silakan merujuk ke dokumentasi Play.
Untuk memulai, Anda dapat menambahkan play-ahc-ws-standalone
sebagai ketergantungan di SBT:
LibraryDependencies += "org.playframework" %% "play-ahc-ws-standalone" % "lateR_version" // sebelum versi 3.0.0: LibraryDependencies += "com.typesafe.play" %% "play-ahc-ws- mandiri " %" LateS_Version "
Di mana Anda mengganti LATEST_VERSION
dengan versi yang ditampilkan di gambar ini :.
Ini menambahkan versi mandiri dari Play Ws, didukung oleh AsynchttpClient. Perpustakaan ini berisi API Scala dan Java, di bawah play.api.libs.ws
dan play.libs.ws
Untuk menambahkan dukungan XML dan JSON menggunakan Play-json atau Scala XML, tambahkan yang berikut:
LibraryDependencies += "org.playframework" %% "play-ws-standalone-xml" % playwsstandAloneversion LibraryDependencies += "org.playFramework" %% "play-ws-standalone-json" % playwsstandAloneversion // sebelum versi 3.0.0: LibraryDependencies += "com.typesafe.play" %% "play-ws-standalone-xml" % playwsstandAloneversion LibraryDependencies += "com.typesafe.play" %% "play-ws-standalone-json" % playwsstandAloneversion
Play WS menggunakan versi teduh dari asynchttpclient dan oauthy signpost, masing -masing dikemas ulang di bawah play.shaded.ahc
dan play.shaded.oauth
masing -masing nama paket. Shading asynchttpClient berarti bahwa versi Netty yang digunakan di belakang asynchttpclient sepenuhnya independen dari aplikasi dan bermain secara keseluruhan.
Secara khusus, naungan asynchttpClient berarti bahwa tidak ada konflik versi yang diperkenalkan antara Netty 4.0 dan Netty 4.1 menggunakan Play WS.
Catatan : Jika Anda mengembangkan play-ws dan menerbitkan
shaded-asynchttpclient
danshaded-oauth
menggunakansbt publishLocal
, Anda perlu menyadari bahwa memperbarui~/.ivy2/local
tidak menimpa~/.ivy2/cache
dan karenanya Anda tidak akan melihat Kode teduh Anda yang diperbarui sampai Anda menghapusnya dari cache. Lihat http://eed3si9n.com/field-test untuk lebih jelasnya. Bug ini telah diajukan sebagai SBT/SBT#2687.
Karena Play WS Shades AsynchttpClient, pengaturan default juga diarsir dan jadi jangan mematuhi dokumentasi AHC. Ini berarti bahwa pengaturan di ahc-default.properties
dan properti sistem asynchttpClient diisi dengan play.shaded.ahc
, misalnya pengaturan usePooledMemory
dalam versi teduh dari asynchttpclient didefinisikan seperti ini:
play.shaded.ahc.org.asynchttpclient.usepooledMemory = true
Sistem tipe di Play-WS telah berubah sehingga badan permintaan dan badan respons dapat menggunakan tipe yang lebih kaya.
Anda dapat mendefinisikan bodywrening atau bodyreadable Anda sendiri, tetapi jika Anda ingin menggunakan pengaturan default di luar kotak, Anda dapat mengimpor pemetaan jenis dengan defaultBodyReadables / DefaultBodBodBodBOrbLITSable.
impor play.api.libs.ws.defaultbodyReadables._import play.api.libs.ws.defaultbodywritables._
Kemungkinan besar Anda akan menginginkan dukungan XML dan JSON:
impor play.api.libs.ws.xmlbodyReadables._import play.api.libs.ws.xmlbodywritables._
atau
impor play.api.libs.ws.jsonbodyreadables._import play.api.libs.ws.jsonbodywritables._
Untuk menggunakan tubuh yang dapat dibaca dalam suatu respons, Anda harus mengetikkan respons secara eksplisit:
impor scala.concurrent. {ExecutionContext, Future} impor play.api.libs.ws.standAlonewscliamMport play.api.libs.ws.xmlbodyreadables._ // ExecuteContext): WS: StandAlonewSclient) (Implain EC: ExecutionContext): Future (WS: StandAlonewSclient) (Implain EC: ExecutionContext): Found .xml.elem] = ws.url ("..."). get (). peta {response => response.body [scala.xml.elem] }
atau menggunakan play-json:
import scala.concurrent.{ ExecutionContext, Future }import play.api.libs.json.JsValueimport play.api.libs.ws.StandaloneWSClientimport play.api.libs.ws.JsonBodyReadables._ // requireddef handleJsonResp(ws: StandaloneWSClient)( EC implisit: ExecutionContext): Future [JSValue] = ws.url ("..."). get (). peta {response => response.body [jsvalue] }
Perhatikan bahwa ada kasus khusus: ketika Anda mengalirkan respons, maka Anda harus mendapatkan tubuh sebagai sumber:
import scala.concurrent.ExecutionContextimport org.apache.pekko.util.ByteStringimport org.apache.pekko.stream.scaladsl.Sourceimport play.api.libs.ws.StandaloneWSClientdef useWSStream(ws: StandaloneWSClient)(implicit ec: ExecutionContext) = ws.url ("..."). stream (). Map {response => val Source: Source [bytestring, _] = response.bodyassource val _ = Sumber // Lakukan sesuatu dengan sumber }
Untuk memposting, Anda harus lulus dalam jenis yang memiliki pemetaan kelas implisit yang dapat ditransfer:
impor scala.concurrent.executionContextImport play.api.libs.ws.defaultbodywritables._ // wajib Dibutuhkan postexampestring (ws: play.api.libs.ws.standAlonewsclient) (ExecutionContext) = {valstandAlonewsclient) (ExecutionContext) = {valstandAndata = "Hello ws.url ("..."). POST (StringData) .map {response => / * Lakukan sesuatu * /} }
Anda juga dapat mendefinisikan body yang dapat dibaca kustom Anda sendiri:
impor play.api.libs.ws.bodyReadableImport play.api.libs.ws.ahc.StandAloneahcwsResponsecase kelas foo (body: string) val implisit foobodyReadable = bodyreadable [foo] {respons =>> impor play.shaded.ahc.org.asynchttpclient. {response => ahcresponse} val ahcesponse = response.asinstanceof [standAloneahcwsresponse] .senanya [ahcresponse] foo (ahcresponse.getresponseBody)) }
atau writ bodywrening:
impor org.apache.pekko.util.bytestringimport play.api.libs.ws. {bodywriting, inmemorybody} val implisit writeableof_foo: bodywrible [foo] = {// https://tools.ietf.org/html/rfc688 -3.2 Bodywritable (foo => inmemorybody (bytestring.fromString (foo.tostring)), "application/vnd.company.category+foo") }
Untuk menggunakan pemetaan tipe default di Java, Anda harus menggunakan yang berikut:
impor play.libs.ws.defaultbodyReadables; import play.libs.ws.defaultbodywritables;
diikuti oleh:
Kelas publik MyClient mengimplementasikan DefaultBodyWritable, defaultBodyReadable {public completionstage <string> dostuff () {return client.url ("http://example.com") .post (body ("Hello World"). ThenApply (Respons -Response -> Response ") .body (string ()) ); } }
Perhatikan bahwa ada kasus khusus: ketika Anda menggunakan aliran, maka Anda harus mendapatkan tubuh sebagai sumber:
kelas myclass {public covionStage <source <bytestring, notused >> readResponseAstream () {return ws.url (url) .stream (). thenApply (response -> response.bodyassource () ); } }
Anda juga dapat memposting sumber:
kelas myclass {public covionStage <string> doStuff () {source <bytestring, notused> source = fromsource (); return ws.url (url) .post (body (sumber)). ThenApply (response -response.body () ); } }
Anda dapat mendefinisikan BodyReadable
kustom:
impor play.libs.ws.ahc.*; impor play.shaded.ahc.org.asynchttpclient.response; kelas fooreadable mengimplementasikan BodyReadable <StandAlonewsResponse, foo> {Public foo apply (Response response) {response Ahcresponse = (Response) (Response) Response. Respons. getunderlying (); return foo.serialize (ahcresponse.getResponseBody (standardcharsets.utf_8)); } }
Anda juga dapat mendefinisikan kustom BodyWritable
Anda sendiri:
kelas publik myClient {private bodywritable <string> somherMethod (string string) {org.apache.pekko.util.bytestring bytestring = org.apache.pekko.util.bytestring.fromstring (string); Return New DefaultBodyWritables.InMemoryBodyWritable (bytestring, "Text/Plain"); } }
Klien mandiri membutuhkan Pekko untuk menangani data streaming secara internal:
Di Scala, cara untuk memanggil layanan web dan menutup klien:
Paket playwsclientImport org.apache.pekko.actor.actorsystemimport org.apache.pekko.stream._import play.api.libs.ws._import play.api.libs. _ impor scala.concurrent.executionContext.implicits._ def main (args: array [string]): unit = {// buat sistem pekko untuk utas dan manajemen streaming val val sistem = aktorsystem () System.RegisterOntermination {System.exit (0) } implisit val materizerizer = SystemMaterializer (System) .MATERIALIZER // Buat klien WS mandiri // tidak ada argumen default ke AHCWSClientConfig yang dibuat dari // "AHCWSCLIENTCONFIGFACTORY.FORCONFIG (configFactory.Load, this.getClassclass.getClassLoader)" valcclassclassclaserer) (configFactory. () hubungi (wsclient) .andthen {case _ => wsclient.close ()} .andthen {case _ => System.Terminate ()} } Def call (wsclient: standAlonewsclient): Future [unit] = { wsclient.url ("http://www.google.com") .get (). Map {response => val statustext: string = response.statustext val body = response.body [string] println (s "got a response $ statustext: $ body") } } }
Anda juga dapat membuat klien mandiri langsung dari instance asynchttpclient:
objek scalaclient {def main (args: array [string]): unit = {// gunakan impor play.shaded.ahc.org.asynchttpclient._val asynchttpclientConfig = new DefaultAnynchttpClientConfig.builder () .setmaxRequestretry (0) .setshutdownquietperiod (0) .setShutdowntimeout (0) .buildval asynchttpclient = new defaultasynchttpclient (asynchttpclientConfig) val wsclient = mandiri baru newahcwsclient (asynchttpclient) // ... } }
Ini berguna ketika ada opsi konfigurasi asynchttpClient yang tidak tersedia di lapisan konfigurasi WS.
Di Java API hampir sama:
Paket playwsclient; impor org.apache.pekko.actor.actorsystem; impor org.apache.pekko.stream.*; impor com.typesafe.config.configfactory; import play.libs.ws.*; impor play.libs.ws. Ahc.*; kelas publik JavaClient mengimplementasikan defaultbodyreadables {private final standAloneAhCwsClient Client; Private Final Actorsystem System; Public Static Void Main (String [] args) {// Siapkan Pekko Materizer untuk menangani streamingFinal string name = "WSClient"; ActorsyStem System = Actorsystem.create (name); System.RegisterOntermination (() -> System.exit (0)); materizalizer materizerizer = SystemMaTerializer.get (System) .MATERATIAZER (); // Buat klien WS dari `application.conf` file, classloader saat ini dan materizer.standAloneAhCwsClient ws = mandalloneahcwsclient.create (ahcwsclientConfigFactory.forconfig (configFactory.load (), System.getClass (). getClassloader ()), bodernactory); javaclient; javaclient (). getClassioner ()), javaclient; javaclient (javaclient = getClassioner ()), javaclient; javaclient = javaclient = javaclient = javaclient = javaclient = javaclient = javaclient (javaclient = javaclient (javaclient). javaclient.run (); } JavaClient (Sistem Actorsystem, klien StandAloneahCwsClient) {this.system = System; this.client = klien; } public void run () {client.url ("http://www.google.com") .get () .whencomplete ((response, throwable) -> {string statustext = response.getStATustext (); string body = response.getbody (string ()); system.out.println ("got a response" + statustext); }) .thenrun (() -> {coba {client.close (); } catch (Exception e) {E.PrintStackTrace (); } }) .thenrun (sistem :: hentikan); } }
Demikian juga, Anda dapat memberikan klien asynchttpclient secara eksplisit dari konfigurasi:
Kelas publik JavaClient mengimplementasikan defaultBodyReadable {public static void main (string [] args) {// ... // atur asynchttpclient langsung dari configAsynchttpClientConfig asynchttpclientConfig = new DefaultAsynchtpClientConfig.bUilder () .setmaxRequestretry (0) .setshutdownquietperiod (0) .setShutdowntimeout (0) .build (); asynchttpclient asynchttpclient = new defaultasynchttpclient (asynchttpclientConfig); // Mengatur WSClient Instance langsung dari asynchttpclient.wsclient client = AhcwsClient baru (asynchttpclient, materizerizer); // ...} }
Mainkan WS Implement HTTP Caching melalui CachingAsynchttpClient, Ahchttpcache dan Cachecontrol, perpustakaan manajemen cache HTTP minimal di Scala.
Untuk membuat klien AHC mandiri yang menggunakan caching, lulus dalam contoh ahchttpcache dengan adaptor cache untuk implementasi yang mendasarinya. Misalnya, untuk menggunakan kafein sebagai cache yang mendasarinya, Anda dapat menggunakan yang berikut:
impor scala.concurrent.futureImport java.util.concurrent.timeunitimport com.github.benmanes.caffeine.cache. {Caffeine, ticker} impor play.api.libs.ws.ahc.standAloneHcwsclientImport.api.apib.ahc.standAntoneHcwsclientImport.api.apib.ahc.standAndAnhcwsclientImport.api. Cache. {Ahchttpcache, cache, efektif, responseentry} kelas caffeineHttpcache memperluas cache {val mendasar = caffeine.newbuilder () .ticker (ticker.systemTicker ()) .ExireAfterWrite (365, Timeunit.days) .build [Efektifurikey, responseentry] () def hapus (kunci: efektif) = masa depan.successful (opsi (mendasar. (kunci, entri)) def get (tombol: efektifurikey) = masa depan }def withCache(implicit m: org.apache.pekko.stream.Materializer): StandaloneAhcWSClient = { implicit def ec = m.executionContext val cache = new CaffeineHttpCache() StandaloneAhcWSClient(httpCache = Some(new AhcHttpCache(cache))) }
Ada sejumlah pemandu yang membantu menyusun header kontrol cache:
Panduan Mozilla untuk caching http
Mark Nottingham's Guide to Caching
Caching http
Istirahat Mudah: HTTP Cache
Lihat https://github.com/playframework/.github/blob/main/releasing.md
Play WS dilisensikan di bawah lisensi Apache, versi 2. Lihat file lisensi untuk informasi lebih lanjut.