§Play WS API
Bazen Play uygulaması içinde diğer HTTP servisleri çağırmak isteriz. Play asenkron HTTP istekler yapmayı sağlayan, WS library ile bunu destekler.
WS API’yi kullanırken iki önemli parça vardır: istek yapmak ve cevabı işlemek. Öncelikle nasıl GET ve POST HTTP istekleri yapılır onu tartışacağız, ardından WS’den gelen cevabı işlemeyi göstereceğiz. Sonunda, bazı ortak kullanım durumlarını tartışacağız.
§İstek Yapmak
WS kullanmak için, öncelikle build.sbt
dosyasına javaWs
eklenmelidir:
libraryDependencies ++= Seq(
javaWs
)
Ardından, devamı belirtilmelidir:
import play.libs.ws.*;
import play.libs.F.Function;
import play.libs.F.Promise;
HTTP isteği oluşturmak için, WS.url()
ile bağlantıyı belirterek başlayın.
WSRequestHolder holder = WS.url("http://example.com");
Bu başlık ayarları gibi çeşitli HTTP özelliklerini belirmek için kullanabileceğiniz WSRequestHolder
döndürecektir. Karışık istekler oluşturmak için birlikte zincir çağrılar yapabilirsiniz.
WSRequestHolder complexHolder = holder.setHeader("headerKey", "headerValue")
.setTimeout(1000)
.setQueryParameter("paramKey", "paramValue");
Kullanmak istediğiniz HTTP methoduna karşılık gelen bir methodu çağırarak sona erdirebilirsiniz. Bu zinciri sonlandıracaktır ve WSRequestHolder
’da oluşturulan tüm seçenekleri kullanacaktır.
Promise<WSResponse> responsePromise = complexHolder.get();
WSResponse
’un sunucudan dönen veriyi içerdiği Promise<WSResponse>
döndürür.
§Doğrulamalı istekler
Eğer HTTP doğrulamasına ihticacınız varsa, kullanıcı adı, şifre ve WSAuthScheme
kullanarak kurucunun içinde belirtebilirsiniz. WSAuthScheme
için seçenekler BASIC
, DIGEST
, KERBEROS
, NONE
, NTLM
, ve SPNEGO
’dur.
WS.url(url).setAuth("user", "password", WSAuthScheme.BASIC).get();
§Takip yönlendirmeli istekler
HTTP çağrısının sonucu 302 veya 301 yönlendirmesi ise, tekrar cağrı yapmadan bu yönlendirmeyi takip edebilirsiniz.
WS.url(url).setFollowRedirects(true).get();
§Sorgu parametreli istekler
İstek için sorgu parametreleri belirleyebilirsiniz.
WS.url(url).setQueryParameter("paramKey", "paramValue");
§Ek başlıklı istekler
WS.url(url).setHeader("headerKey", "headerValue").get();
Örnek olarak, belirli formatta yalın metin gönderiyorsanız, içerik tipini açıkca belirmek isteyebilirsiniz.
WS.url(url).setHeader("Content-Type", "application/json").post(jsonString);
// OR
WS.url(url).setContentType("application/json").post(jsonString);
§Zaman aşımlı istek
İstek için zaman aşımı belirmek isterseniz, setTimeout
kullanarak milisaniye olarak zaman aşımını belirtebilirsiniz.
WS.url(url).setTimeout(1000).get();
§Form verisi göndermek
url-form-encoded veri göndermek için uygun bir başlık ve biçimlendirilmiş veri ayarlayabilirsiniz.
WS.url(url).setContentType("application/x-www-form-urlencoded")
.post("key1=value1&key2=value2");
§JSON veri göndermek
JSON verisi göndermek için en kolay yol JSON library kullanmaktır.
import com.fasterxml.jackson.databind.JsonNode;
import play.libs.Json;
JsonNode json = Json.newObject()
.put("key1", "value1")
.put("key2", "value2");
WS.url(url).post(json);
§Cevabı işlemek
WSResponse
ile çalışmak Promise
içinde planlanarak halledilir.
§Cevabı JSON olarak işlemek
response.asJson()
çağırarak, cevabı JsonNode
olarak işleyebilirsiniz.
- Java
-
Promise<JsonNode> jsonPromise = WS.url(url).get().map( new Function<WSResponse, JsonNode>() { public JsonNode apply(WSResponse response) { JsonNode json = response.asJson(); return json; } } );
- Java 8
-
Promise<JsonNode> jsonPromise = WS.url(url).get().map(response -> { return response.asJson(); });
§Cevabı XML olarak işlemek
Benzer bir şekilde, response.asXml()
çağırarak cevabı XML olarak işleyebilirsiniz.
- Java
-
Promise<Document> documentPromise = WS.url(url).get().map( new Function<WSResponse, Document>() { public Document apply(WSResponse response) { Document xml = response.asXml(); return xml; } } );
- Java 8
-
Promise<Document> documentPromise = WS.url(url).get().map(response -> { return response.asXml(); });
§Büyük cevapları işlemek
Büyük dosya veya döküman indirirken, WS
cevap gövdesini InputStream
olarak almanıza izin verir, böylece veriyi bütün içeriği bir kerede belleğe yüklemeden işleyebilirsiniz.
- Java
-
final Promise<File> filePromise = WS.url(url).get().map( new Function<WSResponse, File>() { public File apply(WSResponse response) throws Throwable { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = response.getBodyAsStream(); // write the inputStream to a File final File file = new File("/tmp/response.txt"); outputStream = new FileOutputStream(file); int read = 0; byte[] buffer = new byte[1024]; while ((read = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, read); } return file; } catch (IOException e) { throw e; } finally { if (inputStream != null) {inputStream.close();} if (outputStream != null) {outputStream.close();} } } } );
- Java 8
-
Promise<File> filePromise = WS.url(url).get().map(response -> { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = response.getBodyAsStream(); // write the inputStream to a File final File file = new File("/tmp/response.txt"); outputStream = new FileOutputStream(file); int read = 0; byte[] buffer = new byte[1024]; while ((read = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, read); } return file; } catch (IOException e) { throw e; } finally { if (inputStream != null) {inputStream.close();} if (outputStream != null) {outputStream.close();} } });
Bu örnek cevap gövdesini okuyup, arabelleklenen arttırımlarla dosyaya yazacaktır.
§Ortak Motifler ve Kullanım Durumları
§WS Çağrıları Zincirlemek
flatMap
kullanarak zincir WS çağrıları yapabilirsiniz.
- Java
-
final Promise<WSResponse> responseThreePromise = WS.url(urlOne).get().flatMap( new Function<WSResponse, Promise<WSResponse>>() { public Promise<WSResponse> apply(WSResponse responseOne) { String urlTwo = responseOne.getBody(); return WS.url(urlTwo).get().flatMap( new Function<WSResponse, Promise<WSResponse>>() { public Promise<WSResponse> apply(WSResponse responseTwo) { String urlThree = responseTwo.getBody(); return WS.url(urlThree).get(); } } ); } } );
- Java 8
-
final Promise<WSResponse> responseThreePromise = WS.url(urlOne).get() .flatMap(responseOne -> WS.url(responseOne.getBody()).get()) .flatMap(responseTwo -> WS.url(responseTwo.getBody()).get());
§İstisnaları Kurtarmak
Eğer istek içinde istisna durumları kurtarmak istiyorsanız, temcilci cevap için recover
veya recoverWith
kullanınız.
- Java
-
Promise<WSResponse> responsePromise = WS.url("http://example.com").get(); Promise<WSResponse> recoverPromise = responsePromise.recoverWith(new Function<Throwable, Promise<WSResponse>>() { @Override public Promise<WSResponse> apply(Throwable throwable) throws Throwable { return WS.url("http://backup.example.com").get(); } });
- Java 8
-
Promise<WSResponse> responsePromise = WS.url("http://example.com").get(); Promise<WSResponse> recoverPromise = responsePromise.recoverWith(throwable -> WS.url("http://backup.example.com").get() );
§Controller Kullanımı
Promise<WSResponse>
’u Promise<Result>
’a dönüştürerek Handling Asynchronous Results’da tanımlanmış asenkron action motifi kullanarak Play sunucusu tarafından direkt idare edilmesini sağlayabilirsiniz.
- Java
-
public static Promise<Result> index() { final Promise<Result> resultPromise = WS.url(feedUrl).get().map( new Function<WSResponse, Result>() { public Result apply(WSResponse response) { return ok("Feed title:" + response.asJson().findPath("title")); } } ); return resultPromise; }
- Java 8
-
public static Promise<Result> index() { return WS.url(feedUrl).get().map(response -> ok("Feed title: " + response.asJson().findPath("title").asText()) ); }
§WSClient kullanarak
WSClient AsyncHttpClient temilinin kapsayıcısıdır. Çeşitli profillere sahip çoklu istemci tanımlamak veya taklit istek kullanımı için kullanışlıdır
Varsayılan istemci WS sınıfından çağırılabilir:
WSClient client = WS.client();
WS istemcisini doğrudan koddan tanımlayabilir ve bunu istek yapmak için kullanabilirsiniz.
// Set up the client config (you can also use a parser here):
scala.Option<Object> none = scala.None$.empty();
scala.Option<String> noneString = scala.None$.empty();
scala.Option<SSLConfig> noneSSLConfig = scala.None$.empty();
WSClientConfig clientConfig = new DefaultWSClientConfig(
none, // connectionTimeout
none, // idleTimeout
none, // requestTimeout
none, // followRedirects
none, // useProxyProperties
noneString, // userAgent
none, // compressionEnabled
none, // acceptAnyCertificate
noneSSLConfig);
// Build a secure config out of the client config and the ning builder:
AsyncHttpClientConfig.Builder asyncHttpClientBuilder = new AsyncHttpClientConfig.Builder();
NingAsyncHttpClientConfigBuilder secureBuilder = new NingAsyncHttpClientConfigBuilder(clientConfig,
asyncHttpClientBuilder);
AsyncHttpClientConfig secureDefaults = secureBuilder.build();
// You can directly use the builder for specific options once you have secure TLS defaults...
AsyncHttpClientConfig customConfig = new AsyncHttpClientConfig.Builder(secureDefaults)
.setProxyServer(new com.ning.http.client.ProxyServer("127.0.0.1", 38080))
.setCompressionEnabled(true)
.build();
WSClient customClient = new play.libs.ws.ning.NingWSClient(customConfig);
Promise<WSResponse> responsePromise = customClient.url("http://example.com/feed").get();
NOTE: NingWSClient nesnesini temsil ediyorsanız, WS eklenti sistemini kullanmaz, ve bu yüzden
Application.onStop
‘da otomatik olarak kapatılmayacaktır. Bunun yerine, işlemler tamamlanıncaclient.close()
kullanarak elle kapatılmalıdır. Bu AsyncHttpClient tarafından kullanılan ThreadPoolExecutor’ın temelini serbest bırakacaktır. İstemci kapatırken oluşan bozukluk yetersiz bellek hatasına sebep olabilir. (özellikle uygulamanıcı geliştirici modunda sıklıkla kapatıp açıyorsanız).
AsyncHttpClient
’in temelinede erişebilirsiniz.
com.ning.http.client.AsyncHttpClient underlyingClient =
(com.ning.http.client.AsyncHttpClient) WS.client().getUnderlying();
Birkaç durumda bu önemlidir. WS’nin istemciye erişmesi gereken birkaç kısıtlaması vardır.
WS
direkt olarak çoklu parçalı form yüklemeyi desteklemez.Temel istemciyi ile RequestBuilder.addBodyPart kullanabilirsiniz.WS
yayın yapan gövdeyi yüklemeyi desteklemez. Bu durumda, AsyncHttpClient tarafından sağlananFeedableBodyGenerator
kullanmalısınız.
§WS Yapılandırma
WS istemcisini yapılandırmak için aşağıdaki özellikleri application.conf
içinde kullanınız
ws.followRedirects
: İstemciyi 301 ve 302 yönlendirmelerini takip etmek için yapılandırır (ön tanımlı true).ws.useProxyProperties
: Sistemin http vekalet(proxy) ayarlarını kullanmak (http.proxyHost, http.proxyPort) (ön tanımlı true).ws.useragent
: User-Agent başlık alanını yapılandırmak içinws.compressionEnable
: Gzip/deflater sıkıştırmayı kullanmak içintrue
olarak ayarlanmalıdır (ön tanımlı false).
§Zaman Aşımları
WS’de 3 farklı zaman aşımı vardır. Zaman aşımına uğramak WS isteğinin kesilmesine yol açar.
ws.timeout.connection
: Uzak sunucuya bağlanırken beklenen azami süre *(ön tanımlı 120 saniye)ws.timeout.idle
: Beklemede kalınan azami süre (bağlantı kuruldu fakat daha fazla veri için bekleniyor) (ön tanımlı 120 saniye).ws.timeout.request
: İstek almayı kabul etmek için toplam süre (uzak sunucu veri göndermeye devam etse bile istek kesilecektir) (ön tanımlı none, akış bağlantılarına izin vermek için).
İstek zaman aşımı belirli bağlantılarda setTimeout()
kullanılarak geçersiz kılınabilir. (“İstek Yapmak” bölümüne bakınız)
§WS’yi SSL ile Yapılandırma
WS’yi HTTP isteklerini SSL/TLS (HTTPS) üzerinden yapılandırmak için, lütfen WS SSL Yapılandırma’e bakınız.
Sonraki: OpenID servislerine bağlanma
Dokümantasyonun bu çevirisi Play ekibi tarafından yapılmamaktadır. Eğer bir hata bulduysanız, bu sayfanın kaynak kodu burada bulunmaktadır. Dokümantasyon yönergelerini okuduktan sonra lütfen katkı yapmaktan çekinmeyin.