@Deprecated článok
K tomuto článku už existuje novšia verzia.
Inštalácia pysimplesoap
- Predpokladám, že máte nainštalovaný Python.
- Predpokladám, že máte nainštalované
setuptools
. Ak nie, urobte tak pomocou manuálu na stránke nástroja - V inštalačnom adresári Pythonu, v podadresári
Scripts
sa ocitoleasy_install.exe
Nainštalujte
pip
, obal nadsetuptools
, ktorý vylepšuje zopár vecí:c:\Programs\Python>easy_install pip
Nainštalujte
pysimplesoap
, SOAPový klient.pip install pysimplesoap
Nainštalujte
httplib2
, vylepšený HTTP klient pre Python.pysimplesoap
na Windowse je totiž bez neho nervózny.
Ukážkový server [JAX-WS 2.0]
Ukážkový server v Jave:
@WebService
public class ChocolateService {
private List<Chocolate> chocolates = new CopyOnWriteArrayList<Chocolate>();
public ChocolateService() {
chocolates.add(new Chocolate(1L, "Lindt Excellence 70%", 70));
chocolates.add(new Chocolate(2L, "Milka Alpenmilch", 40));
chocolates.add(new Chocolate(3L, "Christmas Angel Figure", 15));
}
@WebMethod
public List<Chocolate> list() {
return chocolates;
}
@WebMethod
public void add(Chocolate chocolate) {
System.out.println(chocolate);
this.chocolates.add(chocolate);
}
}
Vypublikujeme ho cez:
Endpoint endpoint = Endpoint.publish("http://localhost:10000/ws/chocolate", new ChocolateService());
Ukážkový klient [Python]
Jednoduchý klient môže vyzerať nasledovne:
from pysimplesoap.client import SoapClient
client = SoapClient(wsdl="http://localhost:10000/ws/chocolate?wsdl", trace=True, ns="x")
vysledok = client.list("");
print vysledok[0]
Výsledkom je dict
dict
ov:
[
{'return': {'percentage': 70, 'id': 1L, 'title': u'Lindt Excellence 70%'}},
{'return': {'percentage': 40, 'id': 2L, 'title': u'Milka Alpenmilch'}},
{'return': {'percentage': 15, 'id': 3L, 'title': u'Christmas Angel Figure'}}
]
K prvému prvku sa vieme teda dostať cez
vysledok[0]["return"]
Dôležité sú tri zádrhele:
Zapnite traceovanie
Je viac než vhodné si zapnúť _trace_ovanie, teda výpis odchádzajúcich a prichádzajúcich správ; aspoň bude vidieť, čo sa deje na drôte.
Metódy bez parametrov
Metóda list()
nemá na strane servera žiadne parametre. Ak zavoláte z klienta len…
vysledok = client.list();
… JAX-WS server odpovie faultom:
Cannot find dispatch method for {}
Príčinou je telo odchádzajúcej správy
<soap:Body>
</soap:Body>
Áno, naozaj vo vnútri nič nie je a preto úbohý JAX-WS netuší, ktorú metódu spustiť.
Zrejme je to bug vo vnútri pythonovského klienta. „Hackom“ je poslať napr. prázdny reťazec, čo sa namapuje na:
<x:list>
<None/>
</x:list>
To síce vygeneruje nevalidný dokument, ale aspoň povedie ku korektnému zavolaniu služby. Nevalidnosť spočíva v narušení XML schémy vo WSDL, ktorá hovorí, že element nesmie obsahovať podelementy:
<xs:complexType name="list">
<xs:sequence/>
</xs:complexType>
Zapnite explicitné menné priestory
Zapnite si podporu explicitného menného priestoru pre telá správ. JAX-WS z neznámeho dôvodu ignoruje správy s implicitnými mennými priestormi. Bez neho to bude vyzerať:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:x="http://jaxws.novotnyr.ics.upjs.sk/">
<soapenv:Header/>
<soapenv:Body>
<list xmlns="http://jaxws.novotnyr.ics.upjs.sk/">
<None></None>
</list>
</soapenv:Body>
</soapenv:Envelope>
S explicitným menným priestorom (ns = "x"
) bude odchádzajúca správa takáto:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:x="http://jaxws.novotnyr.ics.upjs.sk/">
<soapenv:Header/>
<soapenv:Body>
<x:list>
<None/>
</x:list>
</soapenv:Body>
</soapenv:Envelope>
Skúsenosti ukazujú, že JAX-WS 2.0 si poradí len s druhým spôsobom.
Ukážkový klient 2
Pythonovský klient podporuje aj komplexné typy, a to cez slovníky dict
:
chocolate = dict(id=1, title="Lindt", percentage=0.7)
client.add(chocolate)