Play WS เป็นห้องสมุดไคลเอนต์ HTTP ที่ทรงพลังซึ่งพัฒนาโดยทีมเล่นเพื่อใช้กับ Play Framework มันใช้ AsynchttpClient สำหรับฟังก์ชันการทำงานของไคลเอนต์ HTTP และไม่มีการพึ่งพาการเล่น
เราได้จัดทำเอกสารบางอย่างที่นี่เกี่ยวกับวิธีการใช้ Play WS ในแอพของคุณ (โดยไม่ต้องเล่น) สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการใช้ Play WS ในการเล่นโปรดดูเอกสารการเล่น
ในการเริ่มต้นคุณสามารถเพิ่ม play-ahc-ws-standalone
เป็นการพึ่งพาใน SBT:
LibraryDependencies += "org.playframework" %% "play-ahc-ws-standalone" % "ล่าสุด _version" // ก่อนเวอร์ชัน 3.0.0: LibraryDependencies += "com.typesafe.play" %% "play-ahc-ws-- แบบสแตนด์อโลน " %" ล่าสุด _version "
ที่ที่คุณแทนที่ LATEST_VERSION
ด้วยเวอร์ชันที่แสดงในภาพนี้:
สิ่งนี้จะเพิ่ม Play WS เวอร์ชันแบบสแตนด์อโลนซึ่งได้รับการสนับสนุนโดย ASYNCHTTTPClient ห้องสมุดนี้มีทั้ง Scala และ Java APIs ภายใต้ play.api.libs.ws
และ play.libs.ws
ในการเพิ่มการสนับสนุน XML และ JSON โดยใช้ Play-JSON หรือ Scala XML ให้เพิ่มสิ่งต่อไปนี้:
LibraryDependencies += "org.playframework" %% "play-ws-standalone-xml" % playwsstandaloneversion LibraryDependencies += "org.playframework" %% "play-ws-standalone-json" % playwsstandaloneversion // ก่อนเวอร์ชัน 3.0.0: LibraryDependencies += "com.typesafe.play" %% "play-ws-standalone-xml" % playwsstandaloneversion LibraryDependencies += "com.typesafe.play" %% "play-ws-standalone-json" % playwsstandaloneversion
Play WS ใช้ AsynchttpClient รุ่นแรเงาและ OAuth Signpost, บรรจุใหม่ภายใต้ play.shaded.ahc
และ play.shaded.oauth
ชื่อแพ็คเกจตามลำดับ การแรเงา AsynchttpClient หมายความว่ารุ่นของ netty ที่ใช้อยู่เบื้องหลัง AsynchttpClient นั้นเป็นอิสระจากแอปพลิเคชันและเล่นโดยรวมอย่างสมบูรณ์
โดยเฉพาะการแรเงา AsynchttpClient หมายความว่าไม่มีความขัดแย้งในเวอร์ชันที่แนะนำระหว่าง Netty 4.0 และ Netty 4.1 โดยใช้ Play WS
หมายเหตุ : หากคุณกำลังพัฒนา play-ws และเผยแพร่
shaded-asynchttpclient
และshaded-oauth
โดยใช้sbt publishLocal
คุณต้องทราบว่าการอัปเดต~/.ivy2/local
ไม่ได้เขียนทับ~/.ivy2/cache
ดังนั้นคุณจะไม่เห็น รหัสแรเงาที่อัปเดตของคุณจนกว่าคุณจะลบออกจากแคช ดู http://eed3si9n.com/field-test สำหรับรายละเอียดเพิ่มเติม ข้อผิดพลาดนี้ถูกยื่นเป็น SBT/SBT#2687
เนื่องจาก Play WS Shades AsynchttpClient การตั้งค่าเริ่มต้นจึงมีการแรเงาและอย่าปฏิบัติตามเอกสาร AHC ซึ่งหมายความว่าการตั้งค่าใน ahc-default.properties
และคุณสมบัติระบบ ASYNCHTTPClient นั้นได้รับการเตรียมไว้ล่วงหน้าด้วย play.shaded.ahc
ตัวอย่างเช่นการตั้ง usePooledMemory
ในเวอร์ชันสีเทาของ AsynchttpClient ถูกกำหนดเช่นนี้:
play.shaded.ahc.org.asynchttpclient.usepooledmemory = true
ระบบประเภทใน play-ws มีการเปลี่ยนแปลงเพื่อให้ร่างกายคำขอและร่างกายตอบสนองสามารถใช้ประเภทที่สมบูรณ์ยิ่งขึ้น
คุณสามารถกำหนด bodywritable หรือ body อ่านได้ แต่ถ้าคุณต้องการใช้การตั้งค่าเริ่มต้นจากการตั้งค่ากล่องคุณสามารถนำเข้าการแมปประเภทด้วย defaultBodyReadables / defaultBodyWritables
นำเข้า play.api.libs.ws.defaultbodyreadables._import play.api.libs.ws.defaultbodywritables._
มีโอกาสมากขึ้นที่คุณจะต้องการการสนับสนุน XML และ JSON:
นำเข้า play.api.libs.ws.xmlbodyreadables._import play.api.libs.ws.xmlbodywritables._
หรือ
นำเข้า play.api.libs.ws.jsonbodyreadables._import play.api.libs.ws.jsonbodywritables._
ในการใช้การตอบสนองที่สามารถอ่านได้ในการตอบสนองคุณต้องพิมพ์การตอบกลับอย่างชัดเจน:
นำเข้า scala.concurrent. {ExecutionContext, Future} นำเข้า play.api.libs.ws.standalonewsclientimport play.api.libs.ws.xmlbodyReadables._ // requireddef handlexml (ws: standalonewsclient) .xml.elem] = ws.url ("... "). get (). แผนที่ {response => response.body [scala.xml.elem] -
หรือใช้ play-json:
นำเข้า scala.concurrent. {ExecutionContext, Future} นำเข้า play.api.libs.json.jsvalueimport play.api.libs.ws.standalonewsclientimport play.api.libs.ws.jsonbodyReadables._ // จำเป็น EC โดยนัย: ExecutionContext): อนาคต [JSVALUE] = ws.url ("... "). get (). แผนที่ {response => response.body [jsvalue] -
โปรดทราบว่ามีกรณีพิเศษ: เมื่อคุณสตรีมการตอบกลับคุณควรได้รับร่างกายเป็นแหล่งที่มา:
นำเข้า scala.concurrent.executioncontextimport org.apache.pekko.util.bytestringimport org.apache.pekko.stream.scaladsl.sourceimport play.api.libs.ws.standalonewsclientdefeclientdef ws.url ("... "). สตรีม (). แผนที่ {response => แหล่งที่มา: แหล่งที่มา [bytestring, _] = response.bodyassource val _ = แหล่งที่มา -
ในการโพสต์คุณควรส่งผ่านประเภทที่มีการแมปคลาสโดยนัยของ bodywritable:
นำเข้า scala.concurrent.executioncontextimport play.api.libs.ws.defaultbodywritables._ // จำเป็นต้องมี postexamplestring (ws: play.api.libs.ws.standalonewsclient) (Implication EC: ExecutionContext) = ws.url ("... "). โพสต์ (StringData) .map {response => / * ทำบางสิ่งบางอย่าง * /} -
นอกจากนี้คุณยังสามารถกำหนด bodyreadable ที่กำหนดเองของคุณเอง:
นำเข้า play.api.libs.ws.bodyreadableimport play.api.libs.ws.ahc.standaloneahcwsresponsecase คลาส foo (body: string) โดยปริยาย val foobodyreadable = bodyreadable [foo] {response => นำเข้า play.shaded.ahc.org.asynchttpclient. {response => ahcresponse} val ahcresponse = response.asinstanceof [standaloneahcwsresponse]. Underlying [ahcresponse] foo (ahcresponse.getResponsebody) -
หรือบอดี้บอดี้ที่กำหนดเอง:
นำเข้า org.apache.pekko.util.bytestringimport play.api.libs.ws. {bodywlitable, inmemorybody} โดยปริยาย val writeableof_foo: bodywlitable [foo] = {// https://tools.ietf.org/html/rfc68383883883 -3.2 BodyWatable (foo => inMemorybody (bytestring.fromstring (foo.toString)), "Application/vnd.Company.category+foo") -
ในการใช้การแมปประเภทเริ่มต้นใน Java คุณควรใช้สิ่งต่อไปนี้:
นำเข้า play.libs.ws.defaultbodyreadables; นำเข้า play.libs.ws.defaultbodywritables;
ตามด้วย:
คลาสสาธารณะ MyClient ดำเนินการ defaultBodyWritables, defaultBodyReadables {Public CompletionStage <String> Dostuff () {return client.url ("http://example.com") .post (body ("Hello World")) .Body (String ()) - - -
โปรดทราบว่ามีกรณีพิเศษ: เมื่อคุณใช้สตรีมคุณควรได้รับร่างกายเป็นแหล่งที่มา:
คลาส MyClass {Public PublicionStage <Source <bytestring, Notused >> readResponseasTream () {return ws.url (url) .stream (). thenapply (response -> response.bodyassource () - - -
คุณสามารถโพสต์แหล่งที่มา:
คลาส MyClass {Public PlecityStage <String> Dostuff () {แหล่งที่มา <bytestring, Notused> Source = fromSource (); return ws.url (url) .post (body (แหล่งที่มา)). thenapply - - -
คุณสามารถกำหนด BodyReadable
ที่กำหนดเอง:
นำเข้า play.libs.ws.ahc.*; นำเข้า play.shaded.ahc.org.asynchttpclient.response; คลาสที่สามารถใช้งานได้ getUnderly (); return foo.serialize (ahcresponse.getResponseBody (StandardCharsets.UTF_8)); - -
นอกจากนี้คุณยังสามารถกำหนด BodyWritable
ที่กำหนดเองของคุณเอง:
คลาสสาธารณะ MyClient {Bodywlitable ส่วนตัว <String> SomeotherMethod (สตริงสตริง) {org.apache.pekko.util.bytestring bytestring = org.apache.pekko.util.bytestring.fromstring (String); ส่งคืน defaultbodywritables.inmemorybodywritable ใหม่ (bytestring, "text/plain"); - -
ไคลเอนต์แบบสแตนด์อโลนต้องการ Pekko เพื่อจัดการข้อมูลการสตรีมภายใน:
ในสกาล่าวิธีการโทรออกไปยังบริการเว็บและปิดลูกค้า:
แพ็คเกจ playwsclientimport org.apache.pekko.actor.actorsystemimport org.apache.pekko.stream._import play.api.libs.ws._import play.api.libs.ws.ahc._import scala.concurrent.futureobject scalaclient _ นำเข้า scala.concurrent.executioncontext.implicits._ def main (args: array [string]): unit = {// สร้างระบบ pekko สำหรับเธรดและสตรีมมิ่งการจัดการ Val System = Actorsystem () System.RegisterOntermination {System.Exit (0) } val vitalesizer = systemmaterializer (ระบบ). materializer // สร้างไคลเอนต์ WS แบบสแตนด์อโลน // ไม่มีการโต้แย้งค่าเริ่มต้นไปยัง AHCWSClientConfig ที่สร้างขึ้นจาก // "AHCWSClientConfigFactory.forConfig () โทร (wsclient) . และเธอ {กรณี _ => wsClient.close ()} . และเธอ {case _ => system.terminate ()} } def call (wsclient: standaloNewsClient): อนาคต [หน่วย] = { wsclient.url ("http://www.google.com") .get (). แผนที่ {response => val statustext: string = response.statustext val body = response.body [String] println (s "ได้รับการตอบกลับ $ statustext: $ body")) - - -
นอกจากนี้คุณยังสามารถสร้างไคลเอนต์แบบสแตนด์อโลนได้โดยตรงจากอินสแตนซ์ asynchttpClient:
Object scalaclient {def main (args: array [string]): unit = {// ใช้ import play.shaded.ahc.org.asynchttpclient._val asynchttpClientConfig = ใหม่ defaultAsnchttpClientConfig.builder () .SetMaxRequestry (0) .SetShutdownquietperiod (0) .SetShutDownTimeOut (0) .buildVal ASYNCHTTPClient = ใหม่ defaultAsyNCHTTPClient (ASYNCHTTTPClientConfig) val WSClient = ใหม่ standaloneAHCWSClient - -
สิ่งนี้มีประโยชน์เมื่อมีตัวเลือกการกำหนดค่าแบบอะซินช์ต์ท์เพลิออนซึ่งไม่สามารถใช้งานได้ในเลเยอร์การกำหนดค่า WS
ใน Java API นั้นเหมือนกันมาก:
Package playwsclient; นำเข้า org.apache.pekko.actor.actorsystem; นำเข้า org.apache.pekko.stream.*; นำเข้า com.typesafe.config.configfactory; นำเข้า play.libs.ws.*; นำเข้า play.libs.ws. ahc.*; คลาสสาธารณะ Javaclient ใช้ defaultbodyReadables {ส่วนตัวสุดท้าย standaloneahcwsclient ไคลเอนต์ส่วนตัวระบบระบบนักแสดงขั้นสุดท้ายส่วนตัว; โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// ตั้งค่า pekko miticalizer เพื่อจัดการชื่อสตริงสตรีมมิ่ง Actorsystem.create (ชื่อ); System.registerOntermination (() -> System.Exit (0)); materializer aterializer = systemmaterializer.get (ระบบ). materializer (); // สร้างไคลเอนต์ WS จาก `application.conf` ไฟล์, classloader ปัจจุบันและ aterializer.standaloneahcwsclient ws = standaloneahcwsclient.create (ahcwsclientconfigfactory.forconfig (configfactory.load (), system.getClass (). getClassloader () javaclient.run (); } javaclient (ระบบ Actorsystem, ลูกค้า standaloneahcwsclient) {this.system = system; this.client = ไคลเอนต์; } public void run () {client.url ("http://www.google.com") .get () .WhenComplete ((ตอบกลับ, throwable) -> {String statustext = response.getStatustext (); สตริงตัว = response.getBody (String ()); System.out.println ("ได้รับการตอบกลับ" + statustext); - .thenrun (() -> {ลอง {client.close (); } catch (exception e) {e.printstacktrace (); - - . Thenrun (ระบบ :: สิ้นสุด); - -
ในทำนองเดียวกันคุณสามารถให้ไคลเอนต์ AsynchttpClient ได้อย่างชัดเจนจากการกำหนดค่า:
Javaclient คลาสสาธารณะใช้ defaultbodyReadables {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// ... // ตั้งค่า asynchttpClient โดยตรงจาก configasynchttpClientConfig asynchttpClientConfig = ใหม่เริ่มต้น .SetMaxRequestry (0) .SetShutdownquietperiod (0) .SetShutDownTimeOut (0) .build (); asynchttpClient asynchttpClient = ใหม่ defaultAsynchttpClient (asynchttpClientConfig); // ตั้งค่าอินสแตนซ์ WSClient โดยตรงจาก ASYNCHTTPClient.WSClient Client = ใหม่ AHCWSClient (ASYNCHTTTPClient, MateriONIZER); // ... } -
เล่น WS ใช้ HTTP แคชผ่าน CachingasynchttpClient, AhchttpCache และ CacheControl ซึ่งเป็นไลบรารีการจัดการแคช HTTP ที่น้อยที่สุดใน Scala
ในการสร้างไคลเอนต์ AHC แบบสแตนด์อโลนที่ใช้การแคชให้ส่งผ่านในอินสแตนซ์ของ ahchttpcache ด้วยอะแดปเตอร์แคชไปยังการใช้งานพื้นฐาน ตัวอย่างเช่นในการใช้คาเฟอีนเป็นแคชพื้นฐานคุณสามารถใช้สิ่งต่อไปนี้:
นำเข้า scala.concurrent.futureimport java.util.concurrent.timeunitimport com.github.benmanes.caffeine.cache. แคช. {ahchttpcache, แคช, มีประสิทธิภาพ, repectensentry} คลาส caffeinehttpcache ขยายแคช {val anderlying = caffeine.newbuilder () .ticker (ticker.systemticker ()) .ExpiRefterwrite (365, TimeUnit.days) .build [มีประสิทธิภาพ urikey, responseentry] () def ลบ (คีย์: มีประสิทธิภาพ) = future.successful (ตัวเลือก (พื้นฐาน. (คีย์, รายการ)) def get (คีย์: มีประสิทธิภาพ) = future.successful (ตัวเลือก (คีย์ getifpresent พื้นฐาน)) def close (): unit = underlying.cleanup () } def withcache (โดยปริยาย m: org.apache.pekko.stream.materializer): standaloneahcwsclient = {โดยปริยาย def ec = m.executioncontext แคชวาล -
มีคำแนะนำมากมายที่ช่วยในการรวบรวมส่วนหัวควบคุมแคช:
คู่มือการแคช HTTP's Mozilla
คู่มือการแคชของน็อตติงแฮม
การแคช http
พักผ่อนง่ายๆ: แคช http
ดู https://github.com/playframework/.github/blob/main/releasing.md
Play WS ได้รับอนุญาตภายใต้ใบอนุญาต Apache เวอร์ชัน 2 ดูไฟล์ใบอนุญาตสำหรับข้อมูลเพิ่มเติม