SABUN protokolü. Basit Nesne Erişim Protokolü (SOAP) Genel Açıklama

  • 29.07.2019

SOAP (Basit Nesne Erişim Protokolü) bir istemci ve bir sunucu arasında mesaj aktarımı için standartlaştırılmış bir protokoldür. Genellikle HTTP (S) ile birlikte kullanılır, ancak diğer uygulama katmanı protokolleriyle (örneğin, SMTP ve FTP) çalışabilir.
Test teknikleri açısından SOAP testi, diğer API'lerle çalışmaktan temelde farklı değildir, ancak ön hazırlık (protokol teorisi açısından) ve özel test araçları gerektirir. Bu makalede, hem bir SOAP testçisi (bir problem belirledikten sonra "neyi kavrayacağını" bilmeyen) hem de bir yönetici için eşit derecede yararlı olacak, gerekli bilgi ve becerilerin küçük bir kontrol listesini formüle etmek istiyorum. testçilerin bilgilerini değerlendirmek ve eğitim için planlar geliştirmek zorunda kaldı.

teorik temel

SOAP'ın bir protokol olduğu gerçeği test için çok önemlidir: protokolün kendisini, dayandığı "birincil" standartları ve protokolleri ve (gerektiğinde) mevcut uzantıları incelemeniz gerekir.

XML
XML, HTML'ye benzer bir biçimlendirme dilidir. SOAP yoluyla gönderilen / alınan herhangi bir mesaj, verilerin uygun şekilde yapılandırıldığı ve okunması kolay bir XML belgesidir, örneğin:



Julia
Nataşa
Hatırlatma
Bir makale yazmayı unutmayın!

XML hakkında daha fazla ayrıntı w3schools veya codenet'te (Rusça) bulunabilir. Ad alanlarının tanımına dikkat ettiğinizden emin olun (XML'deki öğeleri tanımlarken çakışmaları çözme yöntemi) - SOAP'ta kullanımları gereklidir.

XSD
Çalışırken, olası XML belgelerinin standart bir açıklamasına sahip olmak ve bunların doğru doldurulup doldurulmadığını kontrol etmek her zaman uygundur. Bunun için bir XML Şema Tanımı (veya kısaca XSD) vardır. Bir test cihazı için XSD'nin iki ana özelliği, veri türlerinin tanımı ve olası değerlere kısıtlamalar getirilmesidir. Örneğin, önceki örnekteki öğe isteğe bağlı hale getirilebilir ve XSD kullanılarak 255 karakterle sınırlandırılabilir:

...







...

SABUN uzantıları
Ayrıca işinizde çeşitli SOAP “uzantıları” ile karşılaşabilirsiniz – WS-* gibi standartlar. En yaygın olanlardan biri, şifreleme ve elektronik imzalarla çalışmanıza izin veren WS-Security'dir. Genellikle, onunla birlikte hizmetinizi kullanma haklarını yönetebileceğiniz WS-Policy kullanılır.

WS-Security kullanan örnek:


Alice
6S3P2EWNP3lQf + 9VC3emNoT57oQ =
YF6j8V / CAqi + 1nRsGLRbuZhi
2008-04-28T10: 02: 11Z

Bu uzantıların tümü, her SOAP hizmetinde kullanılmayan oldukça karmaşık yapılardır; SOAP testi öğrenmenin ilk aşamasında bunları ayrıntılı olarak incelemek, alakalı olması muhtemel değildir.

Enstrümanlar

Zaten anladığınız gibi, SABUN ciddi bir iştir, onunla çalışmak için teoriyi ve sayısız standardı bilmeniz gerekir. Uygulamada, bu karmaşıklık çok fark edilir işçilik maliyetlerine yol açacaktır (örneğin, her seferinde bir defterdeki şemaya bakmak ve istekleri curl ile göndermek gerekli olacaktır). Bu nedenle SOAP ile çalışmayı kolaylaştırmak için araçlar oluşturulmuştur.

XML / XSD Düzenleyicileri
İyi bir test cihazı, dokümantasyon yazma aşamasında test etmeye başlar, bu nedenle devreleri kontrol etmek için özel editörler kullanmak uygundur. En ünlü ikisi Oksijen (platformlar arası) ve Altova'dır (yalnızca Windows); ikisi de ücretlidir. Bunlar, analistlerin hizmetleri tanımlarken aktif olarak kullandıkları çok güçlü programlardır.

Uygulamamda, editörlerin üç özelliğinin faydalı olduğu ortaya çıktı: XSD görselleştirme, XSD'den XML oluşturma ve XSD'ye karşı XML doğrulama.

1. XSD görselleştirme gerekli öğeleri ve nitelikleri ve ayrıca mevcut kısıtlamaları hızlı bir şekilde izole etmenizi sağlayan şemanın görsel bir temsili için gereklidir. Örneğin, bir CheckTextRequest için metin öğesi gereklidir ve üç özniteliğin tümü isteğe bağlıdır ( options özniteliği varsayılan olarak sıfıra ayarlanmıştır).

Şemada birçok tür ve kısıtlama olduğunda görselleştirme gereklidir. Yalnızca buna ihtiyacınız varsa ve özel düzenleyiciler için ödeme yapmak istemiyorsanız, ücretsiz alternatifleri (JDeveloper gibi) düşünebilirsiniz.

2. XSD'ye dayalı XML oluşturma geçerli bir mesaj örneği görmek istediğinizde kullanışlıdır. Mesajın olası doldurulmasını hızlı bir şekilde denemek ve kısıtlamaların nasıl çalıştığının nüanslarını kontrol etmek için kullanıyorum.

3. 2. noktadan itibaren özelliği kullandıktan sonra, XSD'ye karşı XML doğrulaması- yani, mesajın doğruluğunu kontrol edin. Özellikler 2 ve 3 birlikte, hizmetin kendisi geliştirme aşamasındayken bile XSD'deki zor kusurları yakalamanıza olanak tanır.

Test aracı - SoapUI

SOAP testi neredeyse her zaman SoapUI kullanmak anlamına gelir. Bu aracın kullanımı hakkında farklı kaynaklarda (,) okuyabilirsiniz, ancak en etkili yol resmi belgelere aşina olmaktır. 8 koşullu SoapUI yeterlilik seviyesini ayırt ediyorum:

Seviye 1 - İstek gönderebilirim
WSDL tabanlı bir proje oluşturmayı öğrenin. SoapUI sizin için gerekli tüm sorguları üretebilir; doldurmalarının doğruluğunu kontrol etmeniz ve "Gönder" düğmesine basmanız yeterlidir. Doğru sorgular oluşturma becerilerini geliştirdikten sonra, hatalara neden olan yanlış sorgular oluşturma sanatında ustalaşmalısınız.

Seviye 2 - Test Takımları ve Test Durumları yapabilirim
Mini otomatik testler yapmaya başlayın. Test paketleri ve test senaryoları, API test komut dosyaları oluşturmanıza, istekler için veri hazırlamanıza ve alınan yanıtı beklenene göre otomatik olarak kontrol etmenize olanak tanır. İlk başta, sadece sorgu koleksiyonları olarak kullanılabilirler. Örneğin bir kusurunuz varsa ve düzelttikten sonra hızlıca kontrol etmek istiyorsanız, özellikle kusur istekleri için ayrı bir test kiti seçebilirsiniz.

Seviye 3 - İddialar yazabilir
Test senaryolarında ustalaştıktan sonra, onları nasıl otomatik olarak kontrol edilebilir hale getireceğinizi öğrenmeniz faydalı olacaktır. Bundan sonra, artık “gözlerinizle” cevap hakkında bilgi aramanıza gerek kalmayacak: otomatik bir kontrol varsa, vakalar yeşil (kontrol geçildiyse) veya kırmızı (geçmediyse) olarak işaretlenecektir. . SoapUI, çok sayıda olası iddia sağlar, ancak en uygun ve basit olanlar İçerir ve İçermez. Onların yardımıyla, alınan yanıtta belirli bir metnin olup olmadığını kontrol edebilirsiniz. Bu kontroller ayrıca normal ifade aramalarını da destekler.

Seviye 4 - İddialarda XPath ve/veya XQuery kullanma
Selenium kullanan kullanıcı arayüzüne biraz aşina olanlar için XPath tanıdık bir şeydir. Kabaca söylemek gerekirse, XPath bir XML belgesindeki öğeleri aramanıza izin verir. XQuery, XPath'i dahili olarak kullanabilen benzer bir teknolojidir; bu dil çok daha güçlü, SQL'e benziyor. Bu dillerin her ikisi de İddialarda kullanılabilir. Yardımlarıyla yapılan kontroller daha hedefli ve kararlıdır, bu nedenle davalarınız daha güvenilir olacaktır.

Seviye 5 - özel adımları kullanarak karmaşık testler yazabilir

Test senaryoları yalnızca bir istek değil, aynı zamanda birkaç istek içerebilir (örneğin, "bir varlık oluştur" → "bir varlığı dışa aktar" standart kullanıcı senaryosunu taklit etmek istediğinizde). İstekler arasında başka özel adımlar olabilir, örneğin:

  • Mülkler ve Mülk Transferi (verilerin yeniden kullanılmasına ve istekler arasında aktarılmasına yardımcı olur);
  • JDBC İsteği (veritabanından veri almak için kullanılır);
  • Koşullu Git (bir test durumunda dallar veya döngüler yapmanızı sağlar);
  • TestCase'i çalıştırın (bazı tipik sorguları ayrı test senaryolarına getirmeye ve gerektiğinde onları çağırmaya yardımcı olur).

Seviye 6 - Groovy komut dosyalarını kullanma

SoapUI, çeşitli yerlerde Groovy komut dosyaları yazmanıza olanak tanır. En basit durum, $ (=) eklerini kullanarak sorgunun kendisinde veri oluşturmaktır. Her zaman böyle ekler kullanırım:

  • $ (= yeni Tarih (). biçimi ("yyyy-AA-gg'T'HH: aa: ss"))- geçerli tarih ve saati gerekli formatta eklemek için;
  • $ (= java.util.UUID.randomUUID ())- doğru şekilde oluşturulmuş rastgele bir GUID eklemek için.

Komple komut dosyaları, vakalarda ve kontrollerde adımlar olarak kullanılabilir. Bir noktada, beşinci seviyeden birkaç özel adımın aynı anda bir komut dosyasıyla değiştirilebileceğini göreceksiniz.

Seviye 7 - MockServices'i kullanma
WSDL tabanlı SoapUI, Mock nesneleri oluşturabilir. Sahte, bir hizmetin en basit simülasyonudur. "Alaylar"ın yardımıyla, hizmet gerçekten test için kullanılabilir olmadan önce bile test senaryoları yazmaya ve hata ayıklamaya başlayabilirsiniz. Ayrıca geçici olarak kullanılamayan hizmetler için taslak olarak da kullanılabilirler.

Seviye 8 - Tanrı SabunuUI
SoapUI'nin ücretli ve ücretsiz sürümleri arasındaki farkı biliyorsunuz ve kodunuzda SoapUI API'sini kullanıyorsunuz. Eklentileri kullanır ve komut satırı ve / veya CI aracılığıyla vakaları çalıştırırsınız. Test senaryolarınız basit ve bakımı kolaydır. Genel olarak, bu enstrümanda "köpeği yediniz". SoapUI'de bu seviyede ustalaşmış biriyle konuşmaktan mutluluk duyarım. Eğer böyleyseniz - yorumlarda aboneliğinizi iptal edin!

Programlama dilleri ile test etme

YandexSpeller API'sine groovy-wslite kullanılarak yapılan bir isteğin nasıl göründüğüne dair bir örnek vereceğim:

wslite.soap'u içe aktar *
def client = new SOAPClient ("http://speller.yandex.net/services/spellservice?WSDL")
def yanıtı = client.send (SOAPAction: "http://speller.yandex.net/services/spellservice/checkText") (
vücut (
CheckTextRequest ("lang": "ru", "xmlns": "http://speller.yandex.net/services/spellservice") (
metin ("diken")
}
}
}
"error" onaylayın == yanıt.CheckTextResponse.SpellResult.error.s.text ()
"1" iddia et == [e-posta korumalı]()

Bildiğim kadarıyla, henüz SOAP'ı test etmek için üst düzey bir çerçeve (Ret-assured gibi) yok, ancak son zamanlarda ilginç bir araç ortaya çıktı - karate. SOAP ve REST test senaryolarını Cucumber / Gherkin gibi betikler olarak tanımlamak için kullanılabilir. Birçok testçi için karateye dönmek ideal çözüm olacaktır, çünkü vakaları yazmanın ve sürdürmenin karmaşıklığı açısından bu tür senaryolar, SoapUI'yi kullanmak ile kendi SOAP test çerçevenizi yazmak arasında bir yerde olacaktır.

Çözüm

Muhtemelen SOAP'ı sadece kendiniz için test etmek istemeyeceksiniz (REST ile yapabileceğiniz gibi). Ciddi kurumsal çözümlerde kullanılan ağır bir protokoldür. Ancak ağırlığı aynı zamanda testçiye bir hediyedir: kullanılan tüm teknolojiler standartlaştırılmıştır, iş için yüksek kaliteli araçlar vardır. Testçiden istenen tek şey, bunları öğrenme ve kullanma arzusudur.

Bir testçi için gerekli becerilerin bu kontrol listesini bir araya getirelim. Dolayısıyla, SOAP hizmetlerini yeni test etmeye başlıyorsanız, şunları bilmeniz ve kullanabilmeniz gerekir:

  • WSDL.
  • SABUN.
  • XML / XSD düzenleyicileri (XSD oluşturma düzeyinde).
  • SoapUI 1. seviyede.

Gördüğünüz gibi, ana odak standartların incelenmesidir, SoapUI'de sorguları yürütebilmek oldukça basittir. Kendinizi SOAP testine kaptırdıkça daha ciddi beceri ve bilgi gerektiren görevlerle karşı karşıya kalacaksınız, ancak her şeyi bir anda öğrenmeye çalışmamalısınız. Gerçekleştirilen görevlerin karmaşıklık düzeyini artırmadaki tutarlılık çok daha önemlidir. Bu tavsiyeyi takiben, bir gün bu alanda iyi bir uzman olduğunuzu anlayacaksınız!

Önceki bölümde tartışıldığı gibi, Web hizmetleri istemcilerle ve kendi aralarında XML'de mesajlar göndererek iletişim kurar. Bu XML uygulamasının etiketleri, XML belgesi için biçimlendirme kuralları ve belgelerin değiştirilme sırası SOAP tarafından tanımlanır. SOAP, Microsoft ve Userland'de Dave Winer liderliğindeki bir geliştirme ekibi tarafından 1998 yılında oluşturuldu. Protokolün adı - "Basit Nesne Erişim Protokolü" - asıl amacını yansıtır - uzak nesnelerin yöntemlerine erişmek. Protokolün amacı değişti, artık Web servisleri ile gevşek bağlı dağıtılmış uygulamaların bileşenleri arasındaki tüm etkileşimler için bir protokol haline geldi. Artık oldukça basit değil ve nesneler hakkında hiçbir şey söylemiyor. Birçok geliştirici, önceki kısaltmayı koruyarak buna "Hizmet Odaklı Mimari Protokolü" demeyi önerir. Bu girişimleri durdurmak için, SOAP 1.2 spesifikasyonu, "SOAP" kelimesinin artık hiçbir şekilde şifresinin çözülmeyeceğini belirtir.

1999 yılının sonunda, protokolün geliştirilmesi W3C konsorsiyumuna aktarıldı (http:// www.w3.org/).

Mayıs 2000'de, konsorsiyum kendi SOAP 1.1 sürümünü yayınladı. Bir SOAP mesajı, ad alanlarını kapsamlı bir şekilde kullanan bir XML belgesi olarak biçimlendirilir. SOAP 1.1 XML öğesi adları, http://schemas.xmlsoap.org/soap/envelope/ ad alanı tanımlayıcısına başvurur.

2001 yılında, o zamanlar http://www.w3.org/2001/06/soap-envelope adlı bir ad alanına sahip bir SOAP 1.2 taslağı yayınlandı.

SOAP sürümünü tanımlayanın 1.1 veya 1.2 değil, ad alanı tanımlayıcısı olduğunu unutmayın. Sunucu, SOAP mesajını dikkate almaz ve görürse bir hata mesajı döndürür.

ad alanı uyuşmazlığı.

Ben bu satırları yazarken SOAP 1.1 çalışır durumda kalıyor. Sürüm 1.2, hazırlık aşamasından hiçbir şekilde çıkamaz, ancak örneğin SOAP :: Lite, Apache SOAP 2.3, Apache Axis'te zaten kullanılmaktadır. Bu nedenle, bu bölümde sürüm 1.2'yi tanıtacağım ve sürüm 1.1'den farklılıklarına dikkat çekeceğim.

SOAP çalışma versiyonu spesifikasyonu her zaman http://www.w3.org/TR/SOAP/ adresinde tutulur. Bu adresteki belgeler, çalışan sürüm değiştirildiğinde yenileri ile değiştirilir.

SABUN taslağı sürekli olarak güncellenir ve ad alanı tanımlayıcısı değişir. Bu yazının yazıldığı tarihteki en son taslak http://www.w3.org/TR/soapl2-partl/ adresinde tutuluyordu ve kullandığı ad alanı http://www.w3.org/2002/06/soap idi. - zarf. SOAP 12 spesifikasyonunun iki kısımdan oluştuğuna dikkat edin: 1. kısım ve 2. kısım. Belirtimin ikinci kısmı olan ek, karmaşık veri türlerinin yazılmasına ilişkin kuralları içerir. SABUN 1.2 kurallarına dayalı örnek mesajlar olan spesifikasyonun başka bir bölümü olan partO vardır.

SABUN mesaj yapısı

Spesifikasyon, bir SOAP mesajını, bir belge türü bildirimi ve işleme talimatları içermeyen bir XML belgesi olarak tanımlar. Bu XML belgesinin kök öğesi ... Bir öğe, ad alanlarını tanımlayan niteliklere sahip olabilir,

ve diğer önek özellikleri. Kök öğe, mesaj başlığını içeren bir isteğe bağlı öğe ve bir gerekli öğe içerir. , mesajın içeriğinin yazıldığı yer. Gövdeden sonra 1.1 sürümüne izin verilir keyfi öğeleri yazmak için adlarının önüne eklenmesi gerekiyordu. Sürüm 1.2, bir öğeden sonra herhangi bir şey yazmaya izin vermiyor ... Kısacası, bir SOAP mesajının genel yapısı şöyledir:

xmlns: env = "http://www.w3.org/2002/06/soap-envelope">

< ! - Блоки заголовка ->

eleman

mesajda ise, önce öğenin gövdesine yazılır ... xmlns özniteliklerine ek olarak, iletinin URI tarafından hedeflendiği belirli SOAP sunucusunu belirten bir aktör özniteliğine sahip olabilir.

Mesele şu ki, bir SOAP mesajı birden fazla SOAP sunucusundan veya tek bir sunucudaki birden fazla uygulamadan geçebilir. Bu uygulamalar, mesaj başlık bloklarını önceden işler ve birbirlerine iletir. Bu sunucuların ve/veya uygulamaların tümüne SOAP düğümleri denir. SOAP belirtimi, bir mesajın sunucular zincirinden geçirilmesi için kuralları tanımlamaz. Bunun için, örneğin Microsoft WS-Routing gibi başka protokoller geliştirilmektedir.

aktör özelliği, tüm başlığı işleyecek olan zincirin sonundaki hedef SOAP düğümünü belirtir. Anlam

aktör özniteliği, aktör özniteliğini alan ilk sunucunun, bu bloğun işleyici düğümünü belirterek ayrı başlık bloklarında bulunabileceğini belirtir. İşlemden sonra blok, SOAP mesajından kaldırılır.

1.2 sürümünde, aktör özniteliği rol özniteliği ile değiştirilir, çünkü SOAP'ın bu sürümünde her düğüm bir veya daha fazla rol oynar. Belirtim şu anda bir SOAP düğümü için üç rol tanımlar.

http: //^^.w3.org/2002/06/soap-envelope/role/ultimateReceiver rolü, başlığı işleyecek son hedef düğüm tarafından oynanır.

http://www.w3.org/2002/06/soap-envelope/role/next rolü, bir ara veya hedef düğüm tarafından oynanır. Böyle bir düğüm başka ek roller oynayabilir.

Hiçbir SOAP düğümü http://www.w3.org/2002/06/soap-envelope/role/none rolünü oynamamalıdır.

Dağıtılmış uygulamalar, ihtiyaçlarına göre bu rollere başka roller ekleyebilir, örneğin, dijital imzayı doğrulayan bir ara sunucu tanıtabilir ve bu rolü bazı URI dizeleriyle tanımlayabilir.

Rol niteliğinin değeri, bu başlık bloğunun amaçlandığı düğümün rolünü belirten herhangi bir URI dizesi olabilir. Bu özniteliğin varsayılan değeri, boş bir değerdir, yani yalnızca bir çift tırnak veya http: // \ vw \ v.w3.org/2002/06/soap-envelope/rale/ultimateReceiver URI dizesidir.

Rol niteliğinin değeri, bloğun aynı dize tarafından tanımlanan rolü oynayan bir düğüm tarafından işlenmesi gerektiğini belirtir.

Başka bir öğe özelliği

urnstUnderstand olarak adlandırılan , o veya 1 değerlerini alır. Varsayılan değeri o'dur. mustunderstand özniteliği 1 ise, SOAP düğümü, öğeyi işlerken, belge şemasında tanımlanan sözdizimini dikkate almalı veya mesajı hiç işlememelidir. Bu, mesaj işlemenin doğruluğunu artırır.

SOAP 1.2'de o sayısı yerine false kelimesini, 1 sayısı yerine true kelimesini yazın.

Başlığın gövdesine

önceden başlık girdileri olarak adlandırılan isteğe bağlı öğeleri iç içe yerleştirebilirsiniz. 1.2 sürümünde bunlara başlık blokları denir. Adları mutlaka öneklerle işaretlenmiştir. Başlık blokları, rolü veya aktörü içerebilir ve özellikleri anlamalıdır. Eylemleri yalnızca bu blok için geçerli olacaktır. Bu, bireysel başlık bloklarının, rolü, role özniteliği tarafından belirtilen rolle eşleşen ara SOAP düğümleri tarafından işlenmesine izin verir. Liste 3.1, böyle bir bloğun bir örneğini göstermektedir.

Listeleme 3.1. Bir blok başlığı

xmlns: t = "http://some.com/transaction" env: rol =

"http://www.w3.org/2002/06/soap-envelope/role/ultimateReceiver" env: mustUnderstand = "1">

Başlık blokları içinde yuvalanmış öğeler artık blok olarak adlandırılmıyor. Rol, aktör ve anlaşılması gereken nitelikleri içeremezler.

eleman elemandan hemen sonra yazılmalıdır

mesajda ise veya başlık yoksa SOAP mesajında ​​ilk sırada. öğeye keyfi öğeleri iç içe yerleştirebilirsiniz, belirtim yapılarını hiçbir şekilde tanımlamaz. Ancak, hata mesajını içeren bir öğe tanımlanmıştır.

Hata mesajı

SOAP sunucusu gelen bir SOAP mesajını işlerken bir hata fark ederse, işlemeyi durdurur ve gövdesine bir eleman yazacağı SOAP mesajını istemciye gönderir. bir hata mesajı ile.

Bir SOAP 1.1 elemanının gövdesine yazılan mesajda, çıktı

Aşağıdaki iç içe öğeler tarafından açıklanan dört bölüm vardır.

Hata kodu - hatanın türünü belirten bir mesaj. Hata işleme programı için tasarlanmıştır.

Hata tanımlaması - bir kişiye yönelik hata türünün sözlü açıklaması.

Hatanın yeri hatayı fark eden sunucunun URI'sidir. Bir mesaj, hatanın yapısını netleştirmek için bir SOAP düğüm zincirini geçtiğinde kullanışlıdır. Bu öğeyi yazmak için ara SOAP düğümleri gereklidir, bunu yapmak için hedef SOAP sunucusu gerekli değildir.

Hata detayları - vücutta karşılaşılan hataları tanımlayın mesajlar, ancak başlığında değil. Gövdenin işlenmesi sırasında herhangi bir hata bulunmazsa, bu eleman yoktur.

Örneğin:

xmlns: env = "http://schemas.xmlsoap.org/soap/envelope/">

env: Anlamak Zorundayım SABUN Hatayı Anlamalı

SOAP 1.2, elemanın içeriğini değiştirdi.

ad alanı http://www.w3.org/2002/06/soap-envelope, iki gerekli öğe ve üç isteğe bağlı öğe içerir.

Gerekli unsurlar.

Hata kodu ... Gerekli bir alt öğeyi içerir<:value>hata kodu ve isteğe bağlı iç içe öğe ile yine elementi içeren nitelikli bir hata kodu ve öğe ile , ve sonra her şey özyinelemeli olarak tekrarlanır.

Hatanın nedeni ... İletinin dilini belirten isteğe bağlı bir xml:lang özniteliği (bkz. Bölüm D) ve hatayı açıklayan isteğe bağlı sayıda iç içe öğe içerir.

Isteğe bağlı öğeler.

? - hatayı fark eden ara SOAP düğümünün URI'si.

? - hatayı fark eden SOAP düğümünün rolü.

? - gövde işlenirken görülen hatanın açıklaması mesaj değil, başlık.

Liste 3.2, bir prosedürü yürütmeye çalışırken bir hata mesajı gösterir. Hata, prosedürün argümanlarının adlarının SOAP mesajında ​​doğru yazılmaması ve prosedürün bunları anlayamamasıdır.

Liste 3.2. Hata mesajı

xmlns: env = "http://www.w3.org/2002/06/soap-envelope" xmlns: rpc = 'http: //www.w3.org/2002/06/soap-rpc'>

env: Gönderen

rpc: BadArgumentsc / env: Değer>

Ptocessing ETror

xmlns: e = "http://www.example.org/faults"> No.me eşleşmiyor 999

Hata türleri

Hata kodlarının listesi sürekli değişiyor ve genişliyor. Sürüm 1.1, dört tür hata tanımlar.

VersionMismatch Ad alanı tanınmıyor. Belki eskidir veya adı yanlış yazılmıştır.

MustUnderstand - mustUnderstand özniteliği ile 1 değeriyle işaretlenmiş bir başlık bloğu, belge şemasında tanımlanan sözdizimine uymuyor.

İstemci - Mesajı içeren XML belgesi hatalı biçimlendirilmiş ve bu nedenle sunucu onu işleyemiyor. Müşteri mesajı değiştirmelidir.

Sunucu - sunucu, kendi dahili nedenlerinden dolayı doğru şekilde kaydedilmiş bir mesajı işleyemez.

Sürüm 1.2, beş tür hata tanımlar.

VersionMismatch Ad alanı tanınmıyor. Eski olabilir veya adı yanlış yazılmış olabilir veya mesajda bu ad alanında tanımlanmamış bir XML öğesi adı olabilir. Sunucu, öğeyi yanıt başlığına yazar iç içe öğeleri listeleme sunucu tarafından anlaşıldığı gibi doğru ad alanı adları. Sunucu yanıtı Liste 3.3'te gösterilmektedir.

MustUnderstand - mustunderstand özniteliği true olarak ayarlanmış bir başlık bloğu, belge şemasında tanımlanan sözdizimine uymuyor. Sunucu, yanıt başlığına öğeler yazar qname özniteliği geçersiz bloğun adını içerir. Liste 3.4, Liste 3.1'deki başlığın yanlış yazıldığı ortaya çıkarsa sunucunun vereceği yanıtın bir örneğini içerir.

DataEncodingUnknown - mesaj anlaşılmaz veriler içeriyor, belki bilinmeyen bir kodlamayla yazılmışlardır.

Gönderen - İletiyi içeren XML belgesi hatalı biçimlendirilmiş ve bu nedenle sunucu onu işleyemiyor. Müşteri mesajı değiştirmelidir.

Alıcı - sunucu, dahili nedenlerden dolayı doğru yazılmış bir mesajı işleyemiyor, örneğin gerekli XML ayrıştırıcısı eksik.

Sunucu, bu tür hatalara kendi türlerinden bazılarını ekleyebilir. Genellikle

standart türleri detaylandırırlar ve bunlarla ilgili mesajlar öğelerde görünür yukarıda Liste 3.2'de gösterildiği gibi.

? Liste 3.3. VersionMismatch türünde bir hata mesajı içeren sunucu yanıtı

xmlns: env = "http://www.w3.org/2002/06/soap-envelope">

xmlns: upg = "http://www.w3.org/2002/06/soap-upgrade">

xmlns: nsl = "http://www.w3.org/2002/06/soap-envelope" />

xmlns: ns2 = "http://schemas.xmlsoap.org/soap/envelope/" />

env: Sürüm Uyuşmazlığı

Sürüm uyuşmazlığı

Liste 3. 4. MustUnderstand hata mesajı ile sunucu yanıtı

xmlns: t = 'http: //some.com/transaction' />

env: Anlamak Zorundayım

Bir veya daha fazla zorunlu başlık anlaşılmadı

Edebiyat:

Khabibullin I. Sh. Java Kullanarak Web Servislerinin Geliştirilmesi. - SPb.: BHV-Petersburg, 2003 .-- 400 s: hasta.

Konu başlığı gerçekten bir soru çünkü Ben kendim ne olduğunu bilmiyorum ve ilk kez bu makale çerçevesinde onunla çalışmaya çalışacağım. Aşağıdaki kodun çalışacağını garanti edebileceğim tek şey, ancak cümlelerim yalnızca tüm bunları nasıl anladığımla ilgili varsayımlar ve tahminler olacaktır. O zaman hadi gidelim ...

Tanıtım

Web servisleri kavramının ne için yaratıldığı ile başlamamız gerekiyor. Bu kavram ortaya çıktığında, dünyada uygulamaların uzaktan etkileşime girmesine izin veren, bir programın başka bir programdaki bazı yöntemleri çağırabildiği, başka bir şehirde veya hatta bir ülkede bulunan bir bilgisayarda çalıştırılabilen teknolojiler zaten mevcuttu. Tüm bunlar RPC (Uzaktan Yordam Çağrısı) olarak kısaltılır. Örnekler arasında CORBA teknolojileri ve Java - RMI (Uzaktan Yöntem Çağırma) yer alır. Ve içlerinde her şey yolunda görünüyor, özellikle CORBA'da, tk. onunla herhangi bir programlama dilinde çalışabilirsiniz, ancak yine de bir şey eksikti. CORBA'nın dezavantajının, herhangi bir güvenlik duvarında gezinen basit HTTP yerine kendi ağ protokollerinden bazılarıyla çalışması olduğuna inanıyorum. Web hizmetinin arkasındaki fikir, HTTP paketlerine yapışacak bir RPC oluşturmaktı. Standardın gelişimi böyle başladı. Bu standardın temel kavramları nelerdir:
  1. SABUN... Bir uzak prosedürü çağırmadan önce, bu çağrıyı bir SOAP XML dosyasında tanımlamanız gerekir. SOAP, web hizmetlerinde kullanılan birçok XML biçimlendirmesinden yalnızca biridir. HTTP üzerinden bir yere göndermek istediğimiz her şey önce bir XML SOAP açıklamasına dönüştürülür, ardından bir HTTP paketine konur ve TCP/IP üzerinden ağ üzerindeki başka bir bilgisayara gönderilir.
  2. WSDL... Bir web servisi var, yani. yöntemleri uzaktan çağrılabilen bir program. Ancak standart, bu programa "evet, yanılmıyorsunuz - bu gerçekten bir web hizmetidir ve ondan bu tür yöntemleri çağırabilirsiniz" diyen bir açıklamanın eklenmesini gerektirir. Bu açıklama, WSDL gibi farklı bir biçime sahip başka bir XML dosyasıyla temsil edilir. Onlar. WSDL, yalnızca bir XML web hizmeti açıklama dosyasıdır ve başka bir şey değildir.
Neden bu kadar kısa sordun? Ve daha ayrıntılı olarak imkansız mı? Muhtemelen yapabilirsiniz, ancak bunun için Mashnin T. "Java Web Servisleri" gibi kitaplara başvurmanız gerekiyor. Orada, ilk 200 sayfa boyunca, SOAP ve WSDL standartlarının her bir etiketinin ayrıntılı bir açıklaması vardır. Yapmalı mıyım? Bence, hayır, tk. tüm bunlar Java'da otomatik olarak oluşturulur ve yalnızca uzaktan çağrılması gereken yöntemlerin içeriklerini yazmanız yeterlidir. Böylece Java'da JAX-RPC gibi bir API ortaya çıktı. Bilmeyen varsa, Java'nın şöyle bir API'si olduğunu söylediklerinde, söz konusu teknolojiyi içine alan bir dizi sınıfa sahip bir paket var demektir. JAX-RPC, uzun bir süre sürümden sürüme gelişti ve sonunda JAX-WS'ye dönüştü. WS açıkçası WebService anlamına gelir ve bunun RPC'nin bu günlerde popüler bir kelimeye basit bir şekilde yeniden adlandırılması olduğunu düşünebilirsiniz. durum böyle değil çünkü Artık web servisleri orijinal fikirden uzaklaştı ve sadece uzak yöntemleri çağırmanıza değil, aynı zamanda sadece SOAP formatında belge mesajları göndermenize de izin veriyor. Buna neden ihtiyaç duyuluyor, henüz bilmiyorum, cevabın "her ihtimale karşı, aniden ihtiyaç duyulacak" olması muhtemel değil. Ben kendim daha deneyimli yoldaşlardan öğrenmek istiyorum. Ve son olarak, sözde RESTful web servisleri için JAX-RS de vardı, ancak bu ayrı bir makalenin konusu. Bu noktada giriş sonlandırılabilir, tk. sonra JAX-WS ile çalışmayı öğreneceğiz.

Genel yaklaşım

Web servislerinin her zaman bir istemcisi ve bir sunucusu vardır. Sunucu bizim web hizmetimizdir ve bazen uç nokta olarak adlandırılır (istemciden gelen SOAP mesajlarının gittiği uç nokta gibi). Aşağıdakileri yapmamız gerekiyor:
  1. Web servisimizin arayüzünü tanımlayın
  2. Bu arayüzü uygula
  3. Web hizmetimizi başlatın
  4. Bir istemci yazın ve gerekli web hizmeti yöntemini uzaktan çağırın
Bir web hizmeti farklı şekillerde başlatılabilir: ya bir ana yöntemle bir sınıfı tanımlayın ve web hizmetini bir sunucu olarak doğrudan başlatın ya da Tomcat veya başka bir sunucuya dağıtın. İkinci durumda, kendimiz yeni bir sunucu başlatmıyoruz ve bilgisayarda başka bir bağlantı noktası açmıyoruz, ancak Tomcat servlet konteynerine “web servis sınıflarını buraya yazdık, lütfen yayınlayın, böylece iletişim kuran herkes web hizmetimizi kullanabilirsiniz ". Web hizmetini başlatma yöntemi ne olursa olsun, aynı istemciye sahip olacağız.

sunucu

IDEA'ya başlayalım ve yeni bir proje oluşturalım Yeni Proje Oluştur... bir isim girelim MerhabaWeb Hizmeti ve düğmeye basın Sonraki, ardından düğme Bitiş... klasörde kaynak paket oluştur ru.javarush.ws... Bu pakette HelloWebService arayüzünü oluşturacağız: package ru. javarush. ws; // bunlar ek açıklamalardır, yani. sınıflarımızı ve yöntemlerimizi işaretlemenin bir yolu, // web servis teknolojisi ile ilgili olarak javax'ı içe aktarın. jws. WebYöntem; javax'ı içe aktarın. jws. İnternet servisi; javax'ı içe aktarın. jws. sabun. SABUN Bağlama; // arayüzümüzün web servis olarak çalışacağını söylüyoruz@İnternet servisi // metotları çağırmak için web servisinin kullanılacağını söyle@SOAPBinding (stil = SOAPBinding. Style. RPC) genel arabirim HelloWebService ( // bu metodun uzaktan çağrılabileceğini söylüyoruz@WebMethod public String getHelloString (Dize adı); ) Bu kodda, WebService ve WebMethod sınıfları annotation olarak adlandırılır ve bizim arayüzümüzü ve onun metodunu bir web servisi olarak işaretlemekten başka bir şey yapmazlar. Aynısı SOAPBinding sınıfı için de geçerlidir. Tek fark, SOAPBinding'in bir parametre açıklaması olmasıdır. Bu durumda style parametresi, web servisinin belge mesajları üzerinden değil, klasik bir RPC olarak çalışacağını söyleyen bir değer ile kullanılır, yani. yöntemi çağırmak için. Arayüzümüzün mantığını uygulayalım ve paketimizde bir HelloWebServiceImpl sınıfı oluşturalım. Bu arada, Impl'deki sınıfın sonunun, arayüzlerin uygulanmasının bu şekilde gösterildiğine göre Java'da bir kural olduğunu not ediyorum (Impl - uygulama kelimesinden, yani uygulamadan). Bu bir gereklilik değildir ve sınıfı istediğiniz gibi adlandırmakta özgürsünüz, ancak iyi formun kuralları bunu gerektirir: paket ru. javarush. ws; // arayüzü tanımlarken olduğu gibi aynı açıklama, javax'ı içe aktarın. jws. İnternet servisi; // ancak burada endpointInterface parametresiyle kullanılır, // web servisimizin arayüzünün tam sınıf adının belirtilmesi@WebService (endpointInterface = "ru.javarush.ws.HelloWebService") genel sınıf HelloWebServiceImpl, HelloWebService'i uygular (@Override public String getHelloString (String name) ( // sadece bir selamlama döndür"Merhaba" + isim + "!" ; )) Web hizmetimizi bağımsız bir sunucu olarak başlatalım, yani. herhangi bir Tomcat ve uygulama sunucusunun katılımı olmadan (bu ayrı bir tartışma konusudur). Bunu yapmak için, klasördeki proje yapısında kaynak bir paket ru.javarush.endpoint oluşturun ve bunun içinde ana yöntemle bir HelloWebServicePublisher sınıfı oluşturun: ru paketi. javarush. uç nokta; // web servisleri ile bir web sunucusu başlatmak için sınıf javax'ı içe aktarın. xml. ws. uç nokta; // web servisimizin sınıfı ithalat ru. javarush. ws. HelloWebServiceImpl; public class HelloWebServicePublisher (public static void main (String... args) ( // web sunucusunu 1986 bağlantı noktasında başlat // ve ilk argümanda belirtilen adreste, // ikinci argümanda iletilen web hizmetini başlat uç nokta. Yayınla ( "http: // localhost: 1986 / wss / merhaba", yeni HelloWebServiceImpl()); )) Şimdi bu sınıfı tıklayarak çalıştıralım Üst Karakter + F10... Konsolda hiçbir şey görünmüyor, ancak sunucu çalışıyor. Bunu tarayıcıya http: // localhost: 1986 / wss / merhaba? Wsdl satırını yazarak doğrulayabilirsiniz. Açılan sayfa bir yandan bilgisayarımızda (localhost) bir web sunucusunun (http://) 1986 portunda başladığını kanıtlarken, diğer yandan web servisimizin WSDL açıklamasını gösterir. Uygulamayı durdurursanız, açıklama ve web hizmetinin kendisi kullanılamaz hale gelir, bu nedenle bunu yapmayacağız, ancak istemciyi yazmaya devam edeceğiz.

Müşteri

proje klasöründe kaynak ru.javarush.client paketini ve içinde HelloWebServiceClient sınıfını ana yöntemle oluşturun: ru paketi. javarush. müşteri; // wsdl açıklamasını almak için gerekli // web servisinin kendisine ulaş java'yı içe aktarın. ağ. URL; // bir URL nesnesiyle çalışırken böyle bir eylem gerçekleşecek java'yı içe aktarın. ağ. MalformedURLException; // wsdl açıklamasıyla xml-ku ayrıştırılacak sınıflar // ve içindeki servis etiketine ulaşın javax'ı içe aktarın. xml. ad alanı. QAd; javax'ı içe aktarın. xml. ws. Hizmet; // web servisimizin arayüzü (daha fazlasına ihtiyacımız var) ithalat ru. javarush. ws. MerhabaWebService; genel sınıf HelloWebServiceClient (genel statik geçersiz ana (String args) MalformedURLException ( // wsdl açıklamasına bir bağlantı oluşturun URL url = yeni url ( "http: // localhost: 1986 / wss / merhaba? wsdl") ; // WSDL açıklamasının ilk etiketinde bir sonraki kurucunun parametrelerine bakarız - tanımlar // targetNamespace özelliğindeki 1. argümana bakın // name özelliğindeki 2. argümana bakın QName qname = new QName ("http: //ws.site/", "HelloWebServiceImplService"); // Artık wsdl açıklamasındaki servis etiketine ulaşabiliriz, Servis hizmeti = Servis. oluştur (url, qname); // ve ardından yuvalanmış bağlantı noktası etiketine kadar, böylece // bizden uzaktaki bir web hizmeti nesnesine bağlantı alın HelloWebService merhaba = hizmet. getPort (HelloWebService. sınıfı); // Yaşasın! Artık uzak yöntemi çağırabilirsiniz. Sistem. dışarı. println (merhaba. getHelloString ("CodeGym")); )) Listedeki koda maksimum yorum yaptım. Ekleyecek bir şeyim yok, bu yüzden çalıştırın (Shift + F10). Konsoldaki metni görmeliyiz: Merhaba, CodeGym! Görmediyseniz, muhtemelen web hizmetini başlatmayı unuttunuz.

Çözüm

Bu konuda, web servislerine kısa bir gezi sunuldu. Yine, yazdıklarımın çoğu, nasıl çalıştığına dair benim tahminim ve bu nedenle çok fazla güvenilmemeliyim. Bilgili arkadaşlar düzeltirse sevinirim çünkü o zaman bir şeyler öğrenirim. UPD.

Brett McLaughlin Çeviren İlya Chekmenev

SOAP, Basit Nesne Erişim Protokolüdür. Onu daha önce hiç duymadıysanız, medeniyetten uzak, vahşi bir yerde yaşıyor olmalısınız. Web programlamada tüm öfke haline geldi ve en son nesil web geliştirmede bu tür fanatizmle kullanılan web hizmetlerinin ayrılmaz bir parçası. .NET'i, Microsoft'un buluşu veya eşler arası "devrimi" duyduysanız, SOAP kullanan teknolojileri de duymuşsunuzdur (ne olduğunu bilmeseniz bile). öyle biri yok ama 2 MSDN destek sitesinde (http://msdn.microsoft.com/) binlerce sayfa bulunan Apache ve Microsoft'tan SOAP uygulamaları.

Bu yazıda size SOAP'ın ne olduğunu ve web programlama paradigmasının evriminde neden bu kadar önemli bir parçası olduğunu anlatacağım. Bu, temel bilgileri atlamanıza ve doğrudan SOAP araç setine atlamanıza yardımcı olacaktır. Ardından mevcut SOAP projelerine hızlı bir genel bakış sunacağım ve Apache uygulamasının daha derinlerine ineceğim. Bu makale, SOAP'ın tam resmini yeniden oluşturma iddiasında değil, kitabım Java ve XML 2. Baskı birçok boşluğu doldurdu. Bu makaleyi okuduktan sonra ortaya çıkan birçok sorunun cevabını kitapta bulacaksınız.

Tanıtım

Öncelikle SOAP'ın ne olduğunu anlamanız gerekir. W3C Görüşünün tamamını (ve çok uzun) http://www.w3.org/TR/SOAP adresinde okuyabilirsiniz. Sonra, tüm saçmalıkları ayırıp attıktan sonra, SOAP'ın sadece bir protokol olduğunu anlıyorsunuz. Dağıtılmış bir mimaride bir noktada bilgi alışverişinin gerekli olduğu fikrine dayanan basit bir protokoldür (kullanmak için yeni bir tane yazmaya gerek yoktur). Ayrıca, tıkanıklık olasılığının ve işleme süreçlerinde zorlukların olduğu sistemler için bu protokol, hafif olması ve minimum miktarda kaynak gerektirmesi nedeniyle çok faydalıdır. Son olarak, tüm işlemlerin HTTP üzerinden gerçekleştirilmesine izin verir, bu da güvenlik duvarı gibi zor şeyleri atlamayı ve düşünülemez sayıda bağlantı noktasının soketleri dinlemesini önlemeyi mümkün kılar. Ana şey, bunun farkına varmanızdır ve diğer her şey ayrıntıdır.

Tabii ki, bu detayları bilmek istersiniz ve onları görmezden gelmeyeceğim. SOAP belirtiminde üç temel bileşen vardır: bir SOAP zarfı, bir dizi şifreleme kuralı ve bir istek ile yanıt arasındaki iletişim aracı. Bir SABUN mesajını normal bir mektup gibi düşünelim. Posta pulu ve ön yüzünde adres yazılı zarflardaki bu eski şeyleri hala hatırlıyor musunuz? Bu benzetme, SABUN kavramını bir "zarf" olarak daha iyi görselleştirmenize yardımcı olacaktır. Şekil 12-1, bu benzetme biçiminde SOAP işlemlerini göstermektedir.

Şekil 12-1. SABUN mesaj süreci

Bu resmi göz önünde bulundurarak, SOAP spesifikasyonunun üç bileşenine bir göz atalım. Bu kavramı en iyi temsil eden örnekler vererek her birini kısaca açıklayacağım. Bu üç temel bileşen, SOAP'ı çok önemli ve anlamlı kılmaktadır. Hata işleme, çeşitli şifrelemeler için destek, parametre serileştirme ve çoğu durumda SOAP'ın HTTP üzerinden çalışması, onu diğer dağıtılmış protokol çözümlerinden daha çekici kılmaktadır. SOAP, kitabımda daha ayrıntılı olarak ele aldığım diğer uygulamalarla yüksek derecede birlikte çalışabilirlik sağlar. Şimdilik, SOAP'ın temel unsurlarına odaklanmak istiyorum.

Mektup

Bir SABUN zarfı, normal bir mektup zarfına benzer. Ana SABUN bölümünde, alıcı ve gönderen hakkında bilgilerin yanı sıra mesajın kendisiyle ilgili bilgiler de dahil olmak üzere şifrelenecek mesaj hakkında bilgiler içerir. Örneğin, bir SOAP zarf başlığı, bir mesajın nasıl işlenmesi gerektiğini gösterebilir. Bir uygulama bir mesajı işlemeye başlamadan önce, mesajı işleyip işleyemeyeceği de dahil olmak üzere mesaj hakkındaki bilgileri ayrıştırır. Standart XML-RPC çağrılarındaki durumun aksine (hatırlayın? XML-RPC mesajları, şifreleme, vb., her şey tek bir XML parçasında birleştirilir), SOAP ile, mesaj hakkında bir şeyler bulmak için mevcut işleme gerçekleşir. Tipik bir SOAP mesajı, alıcının mesajı işlemesine yardımcı olmak için bir şifre stili de içerebilir. Örnek 12-1, bir kodlama belirtimi ile biten bir SOAP zarfını göstermektedir.

Örnek 12-1: SABUN Zarfı

sabun kutusu http://www-106.ibm.com/developerworks/library/x-soapbx1.html

Gördüğünüz gibi, şifreleme, uygulamanın (özniteliğin değerini kullanarak) belirlemesini sağlayan zarfın içinde ayarlanır. kodlamaStyle), elemanda bulunan gelen mesajı okuyabilecek mi? Vücut... SOAP zarfının ad alanının doğru olduğundan emin olun, aksi takdirde mesajınızı alan SOAP sunucuları sürüm uyuşmazlığı hatası verir ve onlarla etkileşime geçemezsiniz.

şifreleme

SOAP'ın ikinci önemli unsuru, özel veri türlerini şifreleme yeteneğidir. RPC'de (ve XML-RPC), şifreleme yalnızca indirdiğiniz XML-RPC araç setinde desteklenen önceden tanımlanmış veri türleri üzerinde gerçekleştirilebilir. Diğer veri türlerini şifrelemek, RPC sunucusunu ve istemcisini kendiniz değiştirmenizi gerektirir. SOAP ile XML Şeması, yeni veri türlerini belirtmek için oldukça kolay bir şekilde kullanılabilir (yapıyı kullanarak). karmaşık tip kitabımın 2. Bölümünde tartışılmıştır) ve bu yeni türler, ana SOAP bölümünün bir parçası olarak XML'de temsil edilebilir. XML Schema ile entegrasyon sayesinde, bir SOAP mesajındaki her türlü veriyi bir XML Şeması içinde mantıksal olarak tanımlayarak şifreleyebilirsiniz.

Telefon etmek

Bir SOAP çağrısının nasıl çalıştığını anlamanın en iyi yolu, onu XML-RPC gibi aşina olduğunuz bir şeyle karşılaştırmaktır. Hatırlarsanız, XML-RPC çağrısı Liste 12-2'de gösterilen kod parçacığına benziyor.

Örnek 12-2. XML-RPC'de arama

// Kullanılan XML işleyicisini (ayrıştırıcı) belirtin XmlRpc.setDriver ("org.apache.xerces.parsers.SAXParser"); // XmlRpcClient'e bağlanılacak sunucuyu belirtin istemci = new XmlRpcClient ("http://rpc.middleearth.com"); // Parametre oluştur Vektör parametreleri = yeni Vektör (); params.addElement (uçuşNumarası); params.addElement (numSeats); params.addElement (creditCardType); params.addElement (creditCardNum); // Boolean buyTickets iste = (Boolean) client.execute ("ticketCounter.buyTickets", paragraflar); // Yanıtı işle

Uçak bileti sipariş etmek için en basit programı oluşturdum. Şimdi SOAP'ta aramayı gösteren Örnek 12-3'e bir göz atın.

Örnek 12-3. SABUN Çağrısı

// Parametre oluştur Vektör parametreleri = yeni Vektör (); params.addElement (yeni Parametre ("uçuşNumarası", Tamsayı.sınıf, uçuşNumarası, null)); params.addElement (yeni Parametre ("numSeats", Integer.class, numSeats, null)); params.addElement (yeni Parametre ("creditCardType", String.class,creditCardType, null)); params.addElement (yeni Parametre ("creditCardNumber", Long.class,creditCardNum, null)); // Çağrı nesnesi yarat Çağrı çağrısı = yeni Çağrı (); call.setTargetObjectURI ("urn: xmltoday-airline-tickets"); call.setMethodName ("buyTickets"); call.setEncodingStyleURI (Constants.NS_URI_SOAP_ENC); call.setParams (paramlar); // Çağrı Yanıtı res = call.invoke (yeni URL ("http://rpc.middleearth.com"), ""); // Yanıtı işle

Gördüğünüz gibi, nesne tarafından temsil edilen gerçek çağrı Telefon etmek, bellekte yerleşiktir. Çağrının hedefini, çağrının yöntemini, kodlama stilini, parametreleri ve bu örnekte gösterilmeyen diğer birçok parametreyi belirlemenizi sağlar. XML-RPC yönteminden daha esnektir ve XML-RPC'de dolaylı olarak tanımlanmış bir dizi çeşitli parametreyi açıkça belirtmenize olanak tanır. Bu makalenin ilerleyen bölümlerinde, SOAP'ın geçersiz istekleri nasıl ele aldığı, hata hiyerarşisi ve tabii ki döndürülen çağrı sonuçları dahil, çağırma süreci hakkında daha fazla bilgi edineceksiniz.

Bu kadar kısa bir girişten sonra, zaten bu komik şeyle ilgilenecek kadar bilgi sahibisiniz. Şimdi size kullanacağım SOAP uygulamasını tanıtmama izin verin. Neden seçtiğimi açıklayacağım ve bazı kod örneklerini ele alacağım.

özelleştirme

Artık konsept hakkında temel bir anlayışa sahip olduğunuza göre, eğlenceli kısma geçme zamanı: programlama. Bunu yapmak için, ilk bakışta göründüğünden daha kolay bulunan uygun bir projeye veya ürüne ihtiyacınız var. SOAP yetenekleri sağlayan bir Java projesine ihtiyacınız varsa, onu uzun süre aramanız gerekmez. Ticari ve ücretsiz olmak üzere iki ürün grubu vardır. Kitabımda olduğu gibi ticari ürünlerden bahsetmekten kaçınacağım. Bu hiç de kötü olduklarından değil (tam tersine bazıları güzel), ancak herhangi bir okuyucunun verilen örneklerden herhangi birini denemesini istediğim için. Bunun nedeni, birçok ticari ürünün sahip olmadığı bulunabilirliktir. Bunları kullanmak için ödeme yapmanız veya indirdikten sonra sınırlı bir süre için geçici olarak kullanmanız gerekir.

Böylece açık kaynak projelerine sorunsuz bir şekilde yaklaştık. Bu alanda tek ürün var: Apache SOAP. http://xml.apache.org/soap adresinde bulunur ve Java için SOAP araç takımı sağlar. Bu yazının yazıldığı sırada Apache web sitesinden indirebileceğiniz 2.2 sürümü çıktı. Bu makale için örneklerde kullanacağım sürüm budur.

Diğer alternatifler

Apache SOAP'ı kurmaya ve yapılandırmaya geçmeden önce, aklınıza sızmış olabilecek birkaç soruyu yanıtlayacağım. Ticari ürünler kullanmama nedenlerini de gayet net bir şekilde açıkladım kanaatimce. Bununla birlikte, kullanmak istediğiniz başka açık kaynak projeleri veya ilgili projeleri düşünebilirsiniz ve bunlar hakkında herhangi bir yorum yapmamış olmama şaşırabilirsiniz.

IBM SOAP4J'ye ne dersiniz?

Alternatifler listesinde ilk sırada IBM'den bir uygulama var: SOAP4J. IBM'in çalışması, tıpkı IBM XML4J'nin şu anda Apache Xerces XML Ayrıştırıcı Projesi olarak bilinen projeye dönüşmesi gibi, Apache SOAP projesinin temelini attı. IBM uygulamasının Apache SOAP ile birleşecek şekilde yeniden tasarlanması bekleniyor. Kabaca aynı şey IBM'in XML4J'sinde de oldu: şimdi yalnızca Xerces'te paketleme sağlıyor. Bu yalnızca eğilimin altını çiziyor - büyük üreticiler genellikle OpenSource projelerini destekliyor ve kullanıyor, bu durumda her iki proje de (Apache ve IBM) aynı kod tabanını kullanıyor ...

Microsoft kenarda mı?

Tabii ki hayır. Microsoft ve SOAP uygulamasının yanı sıra tüm .NET alanı (kitabımda daha ayrıntılı olarak ele alınmıştır) önemlidir. Aslında, zamanımın çoğunu Microsoft'un SOAP uygulamasını ayrıntılı olarak incelemek istedim, ancak yalnızca onlar gibi COM nesnelerini destekliyor ve Java'yı desteklemiyor. Bu nedenlerle, Java ve XML ile ilgili bir makaleye böyle bir açıklama eklenememiştir. Yine de Microsoft (geliştiriciler olarak bu şirkete karşı sahip olduğumuz tüm iddialara rağmen) web servisleri alanında önemli çalışmalar yapmış ve sadece çıplak duygularla yönlendirilerek tereddüt etmeden reddederseniz hata yapmış olursunuz. COM veya Visual Basic bileşenleriyle çalışmanız gerekiyorsa, http://msdn.microsoft.com/library/default.asp?url=/nhp/Default.asp adresinde bulunan Microsoft SOAP araç setini kullanmayı denemenizi şiddetle tavsiye ederim. ? contentid = 28000523, diğer birçok SOAP kaynağıyla birlikte.

Eksen nedir?

Apache'yi takip edenleriniz Apache Axis'i duymuş olmalı. Axis, Apache XML çatısı altında geliştirilen yeni nesil bir SOAP araç takımıdır. Son yıllarda hızla ve radikal bir şekilde gelişen SOAP'ın (belirli bir uygulama değil, bir spesifikasyon) takip edilmesi çok zordur. Mevcut gelişen gereksinimlerle tamamen uyumlu bir SOAP sürümü oluşturmaya çalışmak da zordur. Sonuç olarak, Apache SOAP'ın mevcut sürümü, tasarım kısıtlamalı bir çözüm sunar. Mevcut aracı tamamen tersine çevirmeye çalışmamaya karar veren Apache geliştiricileri, yeni koda dayalı bir proje oluşturmaya başladılar. Eksen doğdu. SOAP adı da önce SOAP'tan XP'ye ve ardından XMLP'ye değişti. Daha sonra yeni SABUN'un adından şartnamenin adı çıkarılmış ve "Axis" adı doğmuştur. Ancak şimdi W3C, SOAP spesifikasyonunun (sürüm 1.2 veya 2.0) ismine geri dönüyor gibi görünüyor, bu nedenle işler hala değişebilir ve daha fazla karışıklık olacak!

IBM SOAP4J'yi bir SOAP araç mimarisi olarak mı düşünüyorsunuz? Bir mimari olarak Apache SOAP'a (bu makalede ele alınan) ne dersiniz? Ve Eksen mimari # 3, yeni nesil mimaridir. Bu proje SAX kullanıyor, Apache SOAP ise DOM tabanlı. Ek olarak, Axis, Apache SOAP'tan daha kullanıcı dostu bir yaklaşım sunar. Bu değerleri sıraladıktan sonra, konu olarak neden Axis'i seçmediğimi merak edebilirsiniz. Sadece biraz erken olurdu. Şu anda yalnızca 0.51 Axis sürümü yayınlanmak üzere hazırlanıyor. Henüz beta değil, alfa sürümü bile değil. Axis için yeni özelliklerin ana hatlarını vermeyi çok isterim, ancak kritik sistem ihtiyaçlarınız için alfanın altındaki açık kaynak yazılımları kullanabileceğiniz konusunda yönetiminizi ikna etme şansınız olmaz. Bu yüzden senin gerçek olduğun bir şeye odaklanmaya karar verdim. kullanabilirsinizçoktan bugün- Apaçi SABUNU. Apache Axis'in son sürümü yayınlandığında, bu materyali kitabımın bir sonraki baskısında güncelleyeceğimi düşünüyorum. O zamana kadar, zaten mevcut olan çözüme odaklanalım.

Kurulum

SOAP kurulumunun iki şekli vardır. Birincisi, SOAP mesajlarını kabul edebilen bir sunucuyla iletişim kurmak için SOAP API'sini kullanarak bir SOAP istemcisi başlatmaktır. İkinci yol, SOAP istemcisinden mesaj alabilen bir SOAP sunucusu başlatmaktır. Bu bölümde, her iki prosedürü de açıkladım.

Müşteri

SOAP istemcisini kullanmak için önce http://xml.apache.org/dist/soap adresinde bulunan Apache SOAP'ı indirmeniz gerekir. 2.2 sürümünü ikili biçimde indirdim (alt dizinden sürüm-2.2). Ardından, arşivin içeriğini bilgisayarınızdaki bir dizine açmalısınız. Benim durumumda, dizindi javaxml2 (c: \ javaxml2 Windows bilgisayarımda, / javaxml2 Mac OS X bilgisayarımda). Sonuç olarak, dosyalar açıldı / javaxml2 / sabun-2_2... Ayrıca, http://java.sun.com/products/javamail/ adresindeki Sun'ın sunucusunda bulunan JavaMail paketini de indirmeniz gerekecektir. Apache SOAP tarafından kullanılan SMTP aktarım protokolünün desteklenmesi gerekecektir. Ardından, yine Sun'ın sunucusundan http://java.sun.com/products/beans/glasgow/jaf.html adresinde bulunan Java Beans Activation Framework'ü (JAF) indirin. Halihazırda Xerces veya başka bir XML ayrıştırıcısının kurulu ve kullanıma hazır olduğunu varsayarsak.

Not: XML ayrıştırıcınızın JAXP uyumlu olduğundan ve doğru ad alanını kullandığından emin olun. Ayrıştırıcınız büyük olasılıkla bu gereksinimleri karşılamaktadır.Sorun yaşıyorsanız, Xerces kullanmaya geri dönmek en iyisidir.

Not: Xerces'in en son sürümlerini kullanın. Sürüm 1.4 veya üzeri işinizi görecektir. SOAP ve Xerces 1.3 (.1)'de bir takım buglar var, bu yüzden bu kombinasyonu kullanmamanızı tavsiye ederim.

JavaMail ve JAF paketlerini açın ve jar dosyalarını kütüphanenin yanı sıra sınıf yolunuza ekleyin sabun. kavanoz... Bu jar dosyalarının her biri, ilgili programın kök dizininde veya bir alt dizinde bulunmalıdır. / lib... Tamamlandığında, değişkeniniz sınıf yoluşöyle görünmeli:

$ echo $ SINIF YOLU /javaxml2/soap-2_2/lib/soap.jar:/javaxml2/lib/xerces.jar: /javaxml2/javamail-1.2/mail.jar:/javaxml2/jaf-1.0.1/activation.jar

Windows için şöyle görünecek:

c: \> echo% CLASSPATH% c: \ javaxml2 \ soap-2_2 \ lib \ soap.jar; c: \ javaxml2 \ lib \ xerces.jar; c: \ javaxml2 \ javamail-1.2 \ mail.jar; c: \ javaxml2 \ jaf-1.0.1 \ activation.jar

Son olarak, dizini ekleyin javaxml2 / sabun-2_2 / senin içinde sınıf yolu SOAP örneklerini çalıştırmak için. Bu bölümde birkaç örnek için özelleştirmeyi anlattım.

sunucu

SOAP uyumlu bir sunucu bileşenleri seti oluşturmak için önce bir sunucu uygulaması motoruna ihtiyacınız vardır. Önceki bölümlerde olduğu gibi, bu bölüm için örnek olarak Apache Tomcat'i (http://jakarta.apache.org/ adresinde mevcuttur) kullandım. Müşterinin ihtiyaç duyduğu her şeyi eklemeniz gerekecek sınıf yolu sunucu. Bunu yapmanın en kolay yolu sıfırlamaktır. sabun. kavanoz, aktivasyon.jar ve mail.jar, ayrıştırıcınızın yanı sıra servlet motorunuzun kitaplık dizinine. Tomcat için bu, otomatik yükleme için kitaplıkları içeren / lib dizinidir. Komut dosyası desteği sağlamak istiyorsanız (bu bölümde tartışılmamaktadır, ancak Apache SOAP örneklerinde bulunmaktadır), bsf.jar(http://oss.software.ibm.com/developerworks/projects/bsf adresinde mevcuttur) ve js.jar(http://www.mozilla.org/rhino/ adresinde mevcuttur) aynı dizine.

Not: Xerces'i Tomcat ile kullanıyorsanız, Bölüm 10'da anlattığım numarayı tekrarlamanız gerekecek. ayrıştırıcı.jar v z_parser.jar, a jaxp.jar v z_jaxp.jar emin olmak için xerces.jar ve JAXP'nin dahil edilen sürümü, diğer herhangi bir ayrıştırıcı veya JAXP uygulamasından önce yüklenir.

Ardından, servlet motorunuzu yeniden yükleyin, ardından SOAP sunucu bileşenlerini yazmaya hazırsınız.

Yönlendirici Sunucu Uygulaması ve Yönetici İstemcisi

Temel işlemlerin yanı sıra Apache SOAP, bir yönetici istemcisinin yanı sıra bir yönlendirici sunucu uygulaması içerir. Kullanmayacak olsanız bile SOAP'ın doğru kurulup kurulmadığını test etmek için kurmanızı tavsiye ederim. Bu işlem hangi sunucu uygulaması motorunu kullandığınıza bağlıdır, bu nedenle kendimi Tomcat için yükleme işlemini açıklamakla sınırlayacağım. Diğer sunucu uygulaması motorlarından bazıları için kurulum talimatları http://xml.Apache.org/soap/docs/index.html adresinde bulunabilir.

Tomcat altında kurulum çok kolaydır: sadece dosyayı alın sabun.savaş dizinden sabun-2_2 / webapps ve dizine bırakın $ TOMCAT_HOME / web uygulamaları- bu kadar! Kurulumu kontrol etmek için adresi tarayıcıya girin http: // localhost: 8080 / sabun / sunucu uygulaması / rpcrouter... Şekil 12-2 gibi bir yanıt almalısınız.

Şekil 12-2. RPC yönlendirici sunucu uygulaması

Mesaj bir hata mesajı gibi görünse de her şeyin doğru çalıştığını gösterir. Tarayıcınızda yönetici istemci adresini belirterek aynı yanıtı almalısınız: http: // localhost: 8080 / sabun / sunucu uygulaması / mesaj yönlendirici.

Sunucu ve istemci testinizi tamamlamak için tüm talimatları eksiksiz uyguladığınızdan emin olun. Ardından, RPC yönlendirici sunucu uygulaması için sunucu uygulaması URL'nizi korumak için aşağıda gösterildiği gibi aşağıdaki Java sınıfını çalıştırın:

C: \> Java org.apache.soap.server.ServiceManagerClient http://localhost: 8080 / soap / servlet / rpcrouter listesi Dağıtılan Hizmetler:

Yukarıda gösterildiği gibi boş bir hizmet listesi almalısınız. Herhangi bir mesaj alırsanız, http://xml.Apache.org/soap/docs/trouble/index.html adresinde bulunan olası hataların uzun listesine bakın. Bu, karşılaşabileceğiniz sorunların en kapsamlı listesidir. Boş bir liste alırsanız, yapılandırma tamamlanmıştır ve bu bölümdeki örneklere bakmaya hazırsınız demektir.

Başlayalım

Herhangi bir SOAP tabanlı sistem yazmanın üç ana adımı vardır. Listeledikten sonra, her birine kısaca odaklanacağım:

  • SOAP-RPC ve SOAP mesajları arasında seçim;
  • SOAP hizmeti yazmak veya erişmek;
  • SOAP istemcisi yazma veya erişme.

İlk adım, RPC çağrıları (uzaktan prosedürün sunucuda yürütüldüğü yer) veya mesajlar (istemcinin yalnızca sunucuya bilgi parçalarını gönderdiği yer) için SOAP kullanıp kullanmayacağınızı seçmektir. Bu süreçleri aşağıda ayrıntılı olarak tartışıyorum. Bu kararı verdikten sonra, kendi hizmetinize erişmeniz veya oluşturmanız gerekecektir. Tabii ki, hepimiz Java uzmanı olduğumuz için bu bölüm size kendinizinkini nasıl oluşturacağınızı gösterecektir. Ve son olarak, bu hizmet için bir istemci yazmanız gerekiyor, hepsi bu kadar!

RPC veya Mesajlaşma?

İlk görevinizin programlama ile hiçbir ilgisi yoktur ve daha çok tasarım niteliğindedir. RPC hizmetini mi yoksa mesajları mı kullanacağınızı seçmeniz gerekir. RPC'ye aşina olduğunuzu varsayalım (örneğin, kitabımın bölümlerinden birini okuduktan sonra). İstemci, sunucuda bir uzak prosedür yürütür ve ardından bir yanıt alır. Bu senaryoda, SOAP, daha iyi hata işleme ve ağ üzerinden karmaşık veri türlerinin aktarımını sağlayan zengin bir XML-RPC sistemi görevi görür. Bu konsepte zaten aşinasınız ve RPC sistemlerini SOAP'ta yazmak daha kolay olduğu için onlarla başlayacağım. Bu makalede, bir RPC hizmetinin, bir RPC istemcisinin nasıl oluşturulacağı ve sistemin nasıl kurulup çalıştırılacağı anlatılmaktadır.

SABUN'un başka bir tarzı mesajlaşmadır. Uzaktan prosedürler gerçekleştirmek yerine, yalnızca bilgi alışverişi için kullanılır. Tahmin edebileceğiniz gibi, bu, istemcinin herhangi bir sunucunun bireysel yöntemlerini bilmesini gerektirmeyen güçlü bir araçtır. Ayrıca, veri paketlerinin (mecazi olarak, ağ bağlantılı değil) diğer sistemlere iletim için kullanılmasına izin vererek uzak sistemlerin modellenmesini daha izole hale getirir. Aynı zamanda diğer sistemlerin bu verilerle gerçekleştirilen işlemleri bilmesine gerek yoktur. Bu stil, RPC programlamasından daha karmaşıktır, bu yüzden onu burada tekrarlamayacağım. Bunu, işletmeler arası etkileşimlerin diğer ayrıntılarıyla birlikte kitabımda bulacaksınız. İlk olarak, SOAP-RPC programlamaya bir göz atın.

Çoğu tasarım problemi gibi, bu karar tamamen size kalmış. Uygulamanızı analiz edin ve SOAP'ı ne için kullanmanız gerektiğini belirlemeye çalışın. İsteğe bağlı olarak belirli iş işlevlerini gerçekleştiren bir sunucunuz ve bir dizi istemciniz varsa, RPC sizin için daha uygundur. İletişimin sadece talep üzerine belirli iş fonksiyonlarını yerine getirmekten daha fazlası olduğu karmaşık sistemlerde, SOAP mesajları daha çok tercih edilir.

RPC hizmeti

Formaliteler bittiğine göre artık harekete geçme zamanı. Bildiğiniz gibi, RPC'de yöntemleri uzaktan yürütülecek sınıflara ihtiyacınız var.

kod parçacıkları

Sunucunun kod parçacıklarına bakarak başlayacağım. Bu parçacıklar, RPC istemcileri için yürütülen yöntemlere sahip sınıflardır. Örnek olarak kitabımdan kod kullandım. Basit sınıflar kullanmak yerine, SOAP'ın gücünü olabildiğince açık bir şekilde göstermek için daha karmaşık bir örnek seçtim. Bu yüzden örnek olarak CD sınıfını kullandım. İlk önce elementi tanımlıyoruz. harita standart olmayan her parametre türü için. öznitelik için kodlamaStyle en azından Apache SOAP 2.2'de. http://schemas.xmlsoap.org/soap/encoding/ değerini vermelisiniz. Şu anda, desteklenen tek kodlama budur. Kullanıcı tanımlı tür için bir ad alanı ve ardından bu tür için bir ad alanı öneki ile sınıf adı sağlamanız gerekir. Bizim durumumuzda, bu amaçlar için hayali bir ad alanı ve basit bir önek kullandım " x". Ardından özniteliği kullanarak javaType, Java sınıfının gerçek adını ayarlayın (bu durumda - javaxml2.CD). Ve son olarak, niteliklerle kuralesil java2XMLSınıfAdı ve xml2JavaSınıfAdı... Java'dan XML'e veya tam tersi şekilde dönüştüren bir sınıfı tanımlamak için kullanılırlar. Apache SOAP'ta da bulunan son derece kullanışlı BeanSerializer sınıfını kullandım. Özel parametreniz JavaBean biçimindeyse, bu seri hale getirici ve seri hale getirici, sizi kendinizinkini yazma zahmetinden kurtaracaktır. Varsayılan kurucuya sahip bir sınıfa ihtiyacınız var (unutmayın, CD sınıfı için herhangi bir parametre olmadan basit bir kurucu ayarladım) ve bu sınıfın tüm verilerini yöntemleri kullanarak yayınlayın. setXXX ve almakXXX... sınıftan beri CD tüm bu gereksinimleri mükemmel bir şekilde karşılar, BeanSerileştirici mükemmel çalışıyor.

Not: ne sınıf CD gereksinimleri karşılar BeanSerileştirici... gerçekten önemli değil. Sınıfların çoğu kolayca bu biçime dönüştürülebilir. Bu nedenle, kendi serileştiricilerinizi ve serileştiricilerinizi yazmaktan kaçınmanızı tavsiye ederim. Bu ekstra bir baş ağrısıdır (karmaşık bir şey değil ama çok zahmetli) ve biraz enerji tasarrufu yapmanızı ve özel parametrelerinizde çöp kutusu dönüştürmeyi kullanmanızı öneririm. Çoğu durumda, fasulye dönüşümleri, sınıfınızda yalnızca varsayılan bir kurucu (parametre yok) gerektirir.

Şimdi yeniden oluşturalım kavanoz hizmetimizi dosyalayın ve yeniden konumlandırın:

(gandalf) / javaxml2 / Ch12 $ java org.apache.soap.server.ServiceManagerClient http: // localhost: 8080 / sabun / servlet / rpcrouter xml / CDCatalogDD.xml

Dikkat: Sunucu uygulaması motorunuzu çalışır durumda bırakır ve hizmeti aynı anda yeniden konumlandırırsanız, SOAP hizmeti için yeni sınıfları etkinleştirmek ve hizmeti yeniden konumlandırmak için sunucu uygulaması motorunu yeniden başlatmanız gerekir.

Şimdi, yeni sınıfları ve yöntemleri kullanmak için istemciyi değiştirmeye devam ediyor. Örnek 12-10, istemci sınıfının değiştirilmiş bir sürümünü içerir CDAdder... Önceki sürümde yapılan değişiklikler vurgulanır.

Örnek 12-10: Güncellenmiş CDAdder sınıfı

paket javaxml2; java.net.URL'yi içe aktar; java.util.Vector'u içe aktarın; org.apache.soap.Constants'ı içe aktarın; org.apache.soap.Fault'u içe aktarın; org.apache.soap.SOAPException'ı içe aktarın; org.apache.soap.encoding.SOAPMappingRegistry'yi içe aktarın; org.apache.soap.encoding.soapenc.BeanSerializer'ı içe aktarın; org.apache.soap.rpc.Call'ı içe aktarın; org.apache.soap.rpc.Parameter'ı içe aktar; org.apache.soap.rpc.Response'u içe aktarın; org.apache.soap.util.xml.QName'i içe aktarın; genel sınıf CDAdder ( public void add (URL url, Dize başlığı, Dize sanatçısı, Dize etiketi) SOAPException ( System.out.println ("" "+ başlık +" "sanatçı" "+ sanatçı +" "stüdyolar" + etiket adlı bir CD ekleme); CD cd = yeni CD (başlık, sanatçı, etiket); // Bir çağrı nesnesi yarat Çağrı Çağrı çağrı = yeni Çağrı (); call.setSOAPMappingRegistry (kayıt defteri); call.setTargetObjectURI ("urn: cd-katalog"); call.setMethodName ("addCD"); call.setEncodingStyleURI (Constants.NS_URI_SOAP_ENC); // Parametrelerin ayarlanması Vektör parametreleri = yeni Vektör (); params.addElement (yeni Parametre ("cd", CD.class, cd, null)); call.setParams (paramlar); // Çağrı Yanıtını Çağır yanıtını işleyin; yanıt = çağrı.invoke (url, ""); if (! response.generatedFault ()) (System.out.println ("CD ekleme işlemi başarıyla tamamlandı.");) else (Fault error = response.getFault (); System.out.println (Hata: "+ error.getFaultString) ());)) public static void main (String args) (if (args.length! = 4) (System.out.println ("Şablon: Java javaxml2.CDAdder" + "\" [CD Başlığı] \ "\" [Sanatçı adı] \ "\" [CD Studio] \ ""); dönüş;) deneyin (// URL'ye bağlanılacak SOAP sunucusunun URL'si url = new URL (args); // Yeni CD String için değerleri alın başlık = args; Tel sanatçısı = argümanlar; Dizi etiketi = argümanlar; // CD CDAdder toplayıcısını ekleyin = yeni CDAdder (); adder.add (url, başlık, sanatçı, etiket); ) yakalama (İstisna e) (e.printStackTrace ();)))

Gerçekten ilginç olan tek değişiklik, sınıfın gösterimi ile ilgili. CD:

// SOAP SOAPMappingRegistry ile kullanılabilecek şekilde bu türün eşlenmesi kayıt defteri = new SOAPMappingRegistry (); BeanSerializer serileştirici = yeni BeanSerializer (); register.mapTypes (Constants.NS_URI_SOAP_ENC, yeni QName ("urn: cd-catalog-demo", "cd"), CD.class, serileştirici, serileştirici);

Bu, özel bir parametrenin ağ üzerinden nasıl kodlanabileceği ve aktarılabileceğidir. Sana zaten sınıfın nasıl olduğunu söyledim BeanSerileştirici sınıf gibi JavaBean formatında parametreleri işlemek için kullanılabilir CD... Onları sunucuya yönlendirmek için bir dağıtım tanımlayıcısı kullandım, ancak şimdi istemciye bu serileştiriciyi ve seri kaldırıcıyı kullanmasını söylemem gerekiyor. Bu işlev sınıf tarafından gerçekleştirilir. SABUNHaritalamaKayıt Defteri... Yöntem mapTypes ()şifreli bir dize alır (yine bunun için sabiti kullanmak daha iyidir NS_URI_SOAP_ENC) ve özel serileştirmenin kullanılması gereken parametrenin türü hakkında bilgi. Önce QName belirtilir. Bu nedenle dağıtım tanımlayıcısında garip bir ad alanı kullanıldı. Burada aynı URN'yi ve yerel öğe adını (bu örnek için "CD"), ardından Java nesnesini belirtmeniz gerekir. Sınıf seri hale getirilecek sınıf ( CD.sınıf) ve son olarak serileştirme ve seri durumdan çıkarma için sınıfın bir örneği. Bu örnek için, her iki durumda da bir örnek olacak BeanSerileştirici... Tüm bu ayarlar kayıt defterine girildikten sonra bunu nesneye bildirin. Telefon etmek yöntemi kullanmak setSOAPMapping-Registry ().

Bu sınıfı daha önce gösterildiği gibi bir CD ekleyerek çalıştırabilirsiniz ve her şey beklendiği gibi çalışmalıdır:

C: \ javaxml2 \ build> java javaxml2.CDAdder http: // localhost: 8080 / sabun / sunucu uygulaması / rpcrouter "Tony Rice" "Manzanita" "Sugar Hill" Sugar Hill Studio tarafından "Manzanita" tarafından "Tony Rice" başlıklı bir CD'nin eklenmesi Başarılı CD ekleme.

sınıf değişikliğini bıraktım CDLister Senin için. Her şey aynı düzeni takip ediyor. Kendinizi test etmek için kitabımdaki bu güncellenmiş sınıfları içeren örneklerle dosyalara başvurabilirsiniz.

Not: Buna dersten itibaren karar verebilirsiniz. CDLister doğrudan nesne ile etkileşime girmez CD(yönteme göre döndürülür liste ()önemli olan tür Hashtable), o zaman herhangi bir değişiklik yapmanız gerekmez. Ancak, döndürülen sınıf Hashtable nesne örnekleri içerir CD... SOAP bunları nasıl seri durumdan çıkaracağını bilmiyorsa, istemci bir hata mesajı verir. Bu durumda, sorunu çözmek için nesnede belirtmeniz gerekir. Telefon etmek kopyalamak SABUNHaritalamaKayıt Defteri.

Verimli hata işleme

Artık özel nesnelere, RPC çağrıları yapmaya vb. aşina olduğunuza göre, daha az heyecan verici bir konudan bahsetmeme izin verin: hata işleme. Herhangi bir ağ işleminde birçok hata meydana gelebilir. Hizmet başlamıyor, sunucuda bir hata var, nesne bulunamıyor, sınıflar eksik ve daha birçok sorun var. Şimdiye kadar sadece yöntemi kullandım hata.getString () hata mesajları oluşturmak için. Ancak bu yöntem her zaman yardımcı olmayabilir. Eylem halinde görmek için yapıcıdaki yorumu temizleyin CDKatalog:

genel CDKatalog () ( // katalog = yeni Hashtable (); // dizin oluştur addCD (yeni CD ("Nickel Creek", "Nickel Creek", "Sugar Hill")); addCD (yeni CD ("Let it Fall", "Sean Watkins", "Sugar Hill")); addCD (yeni CD ("Hava Sınırları", "Michael Hedges", "Windham Hill")); addCD (yeni CD ("Taproot", "Michael Hedges", "Windham Hill")); )

Yeniden derleyin, sunucu uygulaması motorunu yeniden başlatın ve yeniden bölümlere ayırın. Bu bir istisna ile sonuçlanacaktır. NullPointerException bir sınıf kurucusu başlatılmamış bir CD'ye bir CD eklemeye çalıştığında Hashtable... İstemciyi başlatırken bir hata mesajı görünecektir, ancak çok bilgilendirici olmayacaktır:

(gandalf) / javaxml2 / inşa $ java javaxml2.CDLister http: // localhost: 8080 / soap / servlet / rpcrouter Geçerli CD dizinini görüntüleyin. Hata: Hedef nesne çözülemiyor: null

Bu, hatayı tespit etmenize ve düzeltmenize yardımcı olabilecek türden bilgiler değildir. Ancak, çerçeve hataları ele alma konusunda iyi bir iş çıkarır. Hatırlıyor musun DOMFaultListeneröğe değeri olarak belirlediğiniz hata Dinleyici? Oyuna girme zamanı gelmişti. Hata durumunda döndürülen nesne Arıza DOM'yi (Belge Nesne Modeli) içerir org.w3c.dom.Öğe Hata hakkında ayrıntılı bilgi ile. Önce import ifadesini kaynak kodunuza ekleyin java.util.Iterator:

java.net.URL'yi içe aktar; java.util.Enumeration'ı içe aktarın; java.util.Hashtable'ı içe aktar; java.util.Iterator'ı içe aktarın; java.util.Vector'u içe aktarın; org.apache.soap.Constants'ı içe aktarın; org.apache.soap.Fault'u içe aktar; org.apache.soap.SOAPException'ı içe aktarın; org.apache.soap.encoding.SOAPMappingRegistry'yi içe aktarın; org.apache.soap.encoding.soapenc.BeanSerializer'ı içe aktarın; org.apache.soap.rpc.Call'ı içe aktarın; org.apache.soap.rpc.Parameter'ı içe aktar; org.apache.soap.rpc.Response'u içe aktarın; org.apache.soap.util.xml.QName'i içe aktarın;

Şimdi list() yöntemindeki hataları işlemek için değişiklikler yapalım:

if (! answer.generatedFault ()) (Parametre returnValue = answer.getReturnValue (); Hashtable kataloğu = (Hashtable) returnValue.getValue (); Numaralandırma e = katalog.keys (); while (e.hasMoreElements ()) (String başlık = (String) e.nextElement (); CD cd = (CD) katalog.get (başlık); System.out.println ("" "+ cd.getTitle () +" "sanatçı" + cd.getArtist () + "studios" + cd.getLabel ());)) else (Hata hatası = response.getFault (); System.out.println ("Hata:" + error.getFaultString ()); Vektör girişleri = error.getDetailEntries (); for (Iterator i = input.iterator (); i.hasNext ();) (org.w3c.dom.Element girişi = (org.w3c.dom.Element) i.next (); System.out.println (giriş .getFirstChild (). getNodeValue ());))

Yöntemi kullanma getDetailEntries () desteklenen bir SOAP hizmetine ve sorunla ilgili bilgiler içeren ham veri sunucusuna erişirsiniz. Kod onları yeniden işler (genellikle yalnızca bir öğe vardır, ancak yakın dikkat gerektirir) ve DOM'yi yakalar eleman her girişte yer alır. Temel olarak, işte çalıştığınız XML:

SOAP-ENV: Server.BadTargetObjectURI hedef çözülemiyor: null İşte istediğimiz bu!

Başka bir deyişle, Fault nesnesi, SOAP zarfının hatalar içeren kısmına erişmenizi sağlar. Apache SOAP ayrıca hata olması durumunda bunları düzeltmek için gereken ayrıntılı bilgileri sağlayan bir Java yığın izlemesi sağlar. Bir elemanı yakalayarak yığın izleme ve düğüm değerini yazdırma Metin bu öğeden müşteriniz bir sunucu yığını izlemesi yazdırabilir. Bu değişiklikleri derlemek ve istemciyi yeniden başlatmak size aşağıdaki çıktıyı verecektir:

C: \ javaxml2 \ build> java javaxml2.CDLister http: // localhost: 8080 / sabun / servlet / rpcr dış Geçerli CD dizinini görüntüleyin. Hata: javaxml2.CDCatalog.addCD'de (CDCatalog.java:24) javaxml2.CDCatalog'da hedef: null Java.lang.NullPointerException çözülemiyor. (CDCatalog.Java:14) Java.lang.Class.newInstance0'da (Yerel Yöntem) Java.lang.Class.newInstance'da (Class.Java:237)

Bu çok daha iyi değil, ama en azından bir istisna atıldığına dair güzel bilgiler görebilirsiniz. NullPointerException hatta bu sorunun oluştuğu sunucu sınıflarındaki satır numaralarını bile bulun. Bu son değişikliklerin sonucu, hata işleme sorununu görsel olarak anlamanızı sağlamıştır. Şimdi sunucu sınıflarınızı hatalar için kontrol etmelisiniz. Evet, neredeyse unutuyordum, ondan önce, sınıfını geri değiştirmeyi unutma CDKatalog netlik için bilerek yaptığımız hatalardan kurtulmak için!

  1. SOAP'ı SMTP (hatta Jabber) gibi diğer protokoller üzerinde çalıştırmak hakkında çok fazla konuşma var. SOAP standardı henüz bunu sağlamamaktadır, ancak gelecekte benzer yetenekler eklenebilir. Bu nedenle, bu konuda aktif tartışmalarla karşılaşırsanız şaşırmayın.

SABUN nedir?

SOAP, Basit Nesne Erişim Protokolü anlamına gelir. Umarım makaleyi okuduktan sonra sadece şaşıracaksınız: "Bu garip isim nedir?"

Mevcut haliyle SOAP, bir ağ üzerinden bir Uzaktan Yordam Çağrısı (RPC) yöntemidir. (Evet, belgeleri XML olarak aktarmak için de kullanılır, ancak şimdilik bunu atlayacağız.)

Anlayalım. Belirli bir hisse senedi sembolü için hisse senedi fiyatı döndüren bir hizmetiniz olduğunu hayal edin. Nasdaq sitesine veri gönderir ve döndürülen HTML'ye göre istenen sonucu üretir. Ayrıca, diğer geliştiricilerin kendi uygulamalarında kullanmasına izin vermek için bu hizmeti İnternet üzerinden teklifler hakkında bilgi bulan bir bileşene dönüştürürsünüz. Bir gün Nasdaq sayfalarının düzenini değiştirene kadar harika çalışıyor. Bileşenin tüm mantığını gözden geçirmeniz ve onu kullanan tüm geliştiricilere güncellemeler göndermeniz gerekir. Ve sırayla, tüm kullanıcılarına güncelleme göndermeleri gerekiyor. Bu düzenli olarak az ya da çok olursa, diğer geliştiriciler arasında çok sayıda düşman edinebilirsiniz. Ve programcılarda bildiğiniz gibi şakalar kötüdür. Yarın ofis öğütücüsünden sevgili kedinizin fotoğrafını çekmek istemezsiniz, değil mi?

Ne yapalım? Bir bakalım ... tek ihtiyacınız olan, girdi olarak (dize türünden) bir kayan nokta alacak ve bir hisse senedi fiyatı (kayan veya çift türden) döndürecek bir işlev sağlamak. Öyleyse, geliştiricilerinizin bu işlevi İnternet üzerinden bir şekilde çağırmasına izin vermek daha kolay olmaz mıydı? İyi! Ayrıca benim için bir haber var, bunu yıllardır yapan COM ve Corba ve Java var ... bu doğru, ancak bu yöntemler hatasız değil. Uzak COM yapılandırması önemsiz değildir. Ayrıca, güvenlik duvarında açılacak o kadar çok port var ki, bira sysadmin'ine doyamazsınız. Evet ve Windows dışındaki tüm işletim sistemlerinin kullanıcılarını unutmanız gerekecek. Ancak Linux kullanıcıları bazen değiş tokuşla da ilgileniyorlar.

DCOM kullanan Linux kullanıcıları için her şey kaybolmamış gibi görünse de, burada daha fazlası var: http://www.idevresource.com/com/library/res/articles/comonlinux.asp.

Corba ve Java hakkında söyleyebileceğim pek bir şey yok, bu yüzden bir alıştırma olarak okuyucuları bu yaklaşımların olumsuz taraflarını bulmaya davet ediyorum.

SOAP, böyle bir uzaktan çağırmayı ve sonucun ne türde döndürüleceğini tanımlamanıza izin veren bir standarttır. Bu nedenle, işlevinizi şebeke üzerinden erişilebilen bir uygulamaya yerleştirmeniz ve aramaları SOAP paketleri şeklinde almanız gerekir. Bundan sonra girişi doğrular, işlevinizi çalıştırır ve sonucu yeni bir SOAP paketinde döndürürsünüz. Tüm süreç HTTP üzerinden çalıştırılabilir, bu nedenle güvenlik duvarınızda bir sürü bağlantı noktası açmanız gerekmez. Basit, değil mi?

Bu makale ne hakkında

Bu, Agni Software'de yazdığımız bir dizi SOAP makalesinin ilkidir. Bu yazımda sizlere SOAP'ın ne olduğunu ve bir SOAP sunucusu ile haberleşen bir uygulama nasıl yazılacağını anlatmaya çalışacağım.

Sabun ve XML

SABUN hala size basit geliyorsa, XML ekleyelim. Şimdi, işlev adı ve parametreleri yerine, kafanızı karıştırmak için tasarlanmış gibi oldukça karmaşık bir XML zarfı alıyoruz. Ama korkmak için acele etmeyin. Daha fazlası var ve SABUN'un karmaşıklığını anlamak için büyük resmi görmeniz gerekiyor.
XML'in ne olduğunu bilmiyorsanız, önce XML ile ilgili makalemi buradan okuyun: http://www.agnisoft.com/white_papers/xml_delphi.asp.

Tüm SOAP paketleri XML formatındadır. Bunun anlamı ne? Görelim. Bu fonksiyona bir göz atın (Pascal):
function GetStockQuote (Sembol: dize): double; Harika görünüyor, ama sorun şu ki Pascal. Bir Java geliştiricisi için bu basit tanımın kullanımı nedir? Veya VB ile çalışan biri için? Herkesin, hatta VB programcılarının bile anlayacağı bir şeye ihtiyacımız var. Bu yüzden onlara aynı bilgileri (parametreler, alıntı değerleri, vb.) içeren XML verin. Temelde işlevinize yapılan bir çağrı olan ve herhangi bir platformdaki herhangi bir uygulamanın anlayabilmesi için XML'e sarılmış bir SOAP paketi oluşturursunuz. Şimdi SOAP çağrımızın neye benzediğini görelim:
xmlns: xsi = "http://www.w3.org/1999/XMLSchema-instance"
xmlns: xsd = "http://www.w3.org/1999/XMLSchema">


IBM


Bilgilendirici, değil mi? SABUN gözlerimizin önünde basitleştirilmiştir. Tamam şaka bir yana. Şimdi sizlere bu SABUN çağrısını nasıl anlamanız gerektiğini açıklamaya çalışacağım.

Etiketlerin kodunu çözme

Gözünüze çarpan ilk etiket ... Bu etiket, özellikle ilgilenmediğimiz, ancak herhangi bir programlama dili veya ayrıştırıcı için çok önemli olan birkaç ad alanı bildirimi içeren bir SOAP paketinin dış sarıcısıdır. Ad alanları, "SOAP-ENV:" veya "xsd:" gibi sonraki öneklerin ayrıştırıcı tarafından ayrıştırılacağı şekilde tanımlanır.

Bir sonraki etiket ... (Burada sunulmayan bir etiketi kaçırdık - ... Bu özel örnekte değil, ancak bununla ilgili daha fazla bilgi edinmek istiyorsanız, buradaki SOAP spesifikasyonuna bakın: http://www.w3.org/TR/SOAP/). Etiket aslında SOAP çağrısını içerir.

Listedeki bir sonraki etiket ... Etiket adı GetStockQuote, çağrılacak işlevdir. SOAP terminolojisinde buna işlem denir. Bu nedenle GetStockQuote yapılması gereken bir işlemdir. ns1, bizim durumumuzda urn: xmethods-quotes'a işaret eden bir ad alanıdır.

Ad alanları hakkında lirik bir arasöz: Ad alanı size bir XML etiketini niteleme yeteneği verir. Örneğin, bir prosedürde aynı ada sahip iki değişkene sahip olamazsınız, ancak bunlar iki farklı prosedürdeyse sorun olmaz. Bu nedenle, bir prosedür, içindeki tüm isimler benzersiz olduğu için bir ad alanıdır. Benzer şekilde, XML etiketlerinin kapsamı ad alanları içindedir, böylece bir ad alanına ve bir etiket adına sahip olarak onu benzersiz bir şekilde tanımlayabilirsiniz. NS1'imizi taklitçilerden ayırt etmek için ad alanını bir URI olarak tanımlayacağız. Yukarıdaki örnekte, NS1, urn: xmethods-quotes'a işaret eden bir takma addır.

EncodingStyle özniteliğine de dikkat edin - bu öznitelik, SOAP çağrısının nasıl serileştirildiğini tanımlar.

etiketin içinde parametreleri içerir. En basit durumumuzda, yalnızca bir parametremiz var - etiket ... Etiketin yanındaki şu satıra dikkat edin:
xsi: type = "xsd: string"
XML'de türler kabaca bu şekilde tanımlanır. (Makale yayınlandıktan sonra değişebilecek olan teknoloji hakkında genelleme yapmak için "hakkında" kelimesini ne kadar akıllıca kullandığıma dikkat edin). Bu tam olarak ne anlama geliyor: xsi ad alanında tanımlanan, fark ettiğiniz tür etikette tanımlanmış - xsd: dize. Ve bu da, xsd ad alanında tanımlanmış, yine daha önce tanımlanmış bir dizedir. (Eminim avukatlar bundan heyecan duyacaktır).

etiketin içinde "IBM" ile belirtilir. Bu, GetStockQuote işlevinin sembol parametresinin değeridir.

Sonunda düzgün insanlar gibi tüm etiketleri kapattık.

Böylece SOAP sunucusuna yapılan çağrıyı tanımlayan SOAP paketini bulduk. Ve SOAP sunucusu, bu çağrının kodunu çözmek ve bir hisse senedi fiyatına ihtiyacınız olduğunu belirlemek için XML ayrıştırıcıları, kırmızı bir düğme ve MIR uzay istasyonunu kullanır. İstenen teklifi hemen bulur ve size şu şekilde verir:
SABUN-ENV: encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" />


34.5


SABUN zarfını açtıktan, kurdeleleri yırttıktan ve sargıyı hışırdattıktan sonra IBM hisse senedi fiyatının 34.5 olduğunu öğreniyoruz.

Çoğu ticari sunucu, son hissenin hangi para biriminde ve hangi fiyattan satın alındığı gibi çok daha fazla bilgi verir. Ve hisse fiyatı belki de daha kesin olurdu.

Bu şekilde SOAP sunucusunun ne beklediğini ve ne döndüreceğini biliyoruz. Peki bu bilgiyi NASIL gönderirsiniz? Herhangi bir ulaşım kullanılabilir. En çok aydınlatılan HTTP'dir. Bilmeyenler için HTTP'nin ayrıntılarına girmeyeceğim - tarayıcınızın ziyaret ettiğiniz sitelerle iletişim kurmak için kullandığı şey budur.

Gerekli HTTP isteği şuna benzer:
POST / Stok Alıntı HTTP / 1.1
Ev sahibi: www.stockquoteserver.com

İçerik Uzunluğu: nnnn
SOAPAction: "Bazı-URI"

Sabun istek paketi burada... Dikkate değer diğer tek şey SOAPAction başlığıdır. Bu başlık, isteğin amacını belirtir ve gereklidir. Her SOAP sunucusunun sınırsız sayıda işlevi olabilir ve hangi işlevin çağrıldığını belirlemek için SOAPAction başlığını kullanabilir. Güvenlik duvarları ve çoklayıcılar da içeriği bu başlığa göre filtreleyebilir.

HTTP sunucusundan gelen SOAP yanıtı şöyle görünecektir:
HTTP / 1.1 200 TAMAM
İçerik Türü: metin / xml; karakter kümesi = "utf-8"
İçerik Uzunluğu: nnnn

Soap Response paketi burada... Neden HTTP? Birincisi, ağ yöneticilerinin SOAP aramaları için bir sürü ayrı port açmasına gerek yok ... web sunucusu aramaları sorunsuz bir şekilde halledebilir. 80 numaralı bağlantı noktası genellikle herkesin gelen istekleri alması için açıktır. Diğer bir avantaj, CGI, ISAPI ve diğer yerel modülleri kullanan web sunucularının genişletilebilirliğidir. Bu genişletilebilirlik, diğer web içeriğini etkilemeden SOAP isteklerini işleyen bir modül yazmanıza olanak tanır.

Bu kadar

Umarım bu makale SOAP'a biraz ışık tutmaya yardımcı olmuştur. Hâlâ buradaysanız ve bu konu hakkında daha fazlasını okumak istiyorsanız, yazarların sitesini ziyaret edin: http://www.agnisoft.com/soap