Webservice'y - jak zrobić to dobrze

520 views
Skip to first unread message

Wojtek K

unread,
Nov 20, 2012, 9:05:50 AM11/20/12
to warsza...@googlegroups.com
Witam Wszystkich,
Mam jakieś moje webservice'y(soap raczej) na serwerze, które będą
konsumowane przez napisanego przeze mnie smart-clienta(Swing czy
JavaFX). Dodatkowo webservice'y mogą być wołane przez inne, zewnętrzne
klienty, może nawet nie w javie. Chciałbym stworzyć jakąś bibliotekę
wspólną na potrzeby smart-client'a i serwera, gdzie znajdowałyby się
interfejsy webserviceów i klasy parametrów i wyników, żeby nie musieć
generować klas klienckich z wsdl'a, a od razu widzieć zmiany przy
modyfikacji wspólnej biblioteki.

Zastanawiam się dodatkowo nad klasami encji. Sporo webservice'ów
powinno je w zasadzie używać 1-1, ale średnio mi się podoba
wystawianie w bibliotece współdzielonej między klienta i serwer jakieś
adnotacje JPA, pomieszane w dodatku z adnotacjami JAXB. Myślę nad
utworzeniem klas parametrów, które w wielu wypadkach różniłyby się
tylko brakiem adnotacji JPA.
Aha, zamierzam używać Metro.

Jak to zrobić fajnie i zgodnie ze sztuką? Jakaś autogeneracja przy
pomocy mavena?
A może robi się to inaczej, coś do poczytania dla mnie?

Pozdrawiam, W.

Olaf Matyja

unread,
Nov 20, 2012, 10:05:15 AM11/20/12
to warsza...@googlegroups.com
No to może JPA skonfiguruj XMLem a nie adnotacjami? Wtedy XMLa wrzucisz tylko na serwerze. To chyba zgrabniejsze od Value Object pattern, które proponujesz zastosować.

Olaf
> --
> Wiadomość z grupy Warszawa Java User Group (Warszawa JUG).
> Więcej informacji na stronie http://groups.google.com/group/warszawa-jug?hl=pl
> Zachęcamy do odwiedzenia naszej strony domowej http://warszawa.jug.pl
> Oferty pracy dozwolone zgodnie z zasadami na oferty pracy na grupie | warszawajug
>

Adam Lider

unread,
Nov 20, 2012, 11:35:17 AM11/20/12
to warsza...@googlegroups.com
Jesli koniecznie chcesz zestaw SOAP+XSD+JAXB to rozwaz podejscie gdzie definiujesz sobie interfejsy w WSDLu i XSDkach i z tego generujesz po stronie klienta i serwera interfejsy i klasy parametrow/wynikow. Jesli uzywasz mavena jest do tego plugin. Jesli Twoj model bedzie zblizony do klas interfejsu pomysl o bibliotece Dozer do mapowania pomiedzy tymi modelami. W innym przypadku "reczne" mapowania bardziej sie sprawdza. Zdecydowane "nie" dla publikowania modelu, ktory sluzy tez do zapisu danych. 
Warto tez rozwazyc CXFa zamiast Metra.

Jesli w ogole SOAP, XSD i JAXB.

--
Adam Lider

--
Wiadomość z grupy Warszawa Java User Group (Warszawa JUG).
Więcej informacji na stronie http://groups.google.com/group/warszawa-jug?hl=pl
Zachęcamy do odwiedzenia naszej strony domowej http://warszawa.jug.pl
Oferty pracy dozwolone zgodnie z zasadami na http://sites.google.com/site/warszawajug/oferty-pracy-na-grupie

Wojtek K

unread,
Nov 20, 2012, 12:51:03 PM11/20/12
to warsza...@googlegroups.com
2012/11/20 Adam Lider <adam....@gmail.com>:
> Jesli koniecznie chcesz zestaw SOAP+XSD+JAXB to rozwaz podejscie gdzie
> definiujesz sobie interfejsy w WSDLu i XSDkach i z tego generujesz po
> stronie klienta i serwera interfejsy i klasy parametrow/wynikow. Jesli
> uzywasz mavena jest do tego plugin. Jesli Twoj model bedzie zblizony do klas
> interfejsu pomysl o bibliotece Dozer do mapowania pomiedzy tymi modelami. W
> innym przypadku "reczne" mapowania bardziej sie sprawdza. Zdecydowane "nie"
> dla publikowania modelu, ktory sluzy tez do zapisu danych.

Nie kręci mnie idea klepania wsdl'a i generowania kodu z tego. Po co
sobie życie utrudniać i grzebać się w wsdlu, skoro można to napisać w
naszym ulubionym języku? Choć, z tego co widzę, podejście top-down
jest często w javie promowane.
Dzięki za Dozera, ciekawe.

> Warto tez rozwazyc CXFa zamiast Metra.

Zgłębiam tajniki Java EE i na razie staram się trzymać standardu.
Podobno od wersji 6 EE daje się używać bez bólu, więc dlatego
patrzyłem na Metro. Widziałem, że wielu narzekało na axis od apache'a.
Czy CXF nie powiela jakichś upierdliwości tamtej biblioteki? W czym
jest lepszy od Metra? Współpracuje dobrze z WCF-em? W Metrze starają
się podobno o to dbać.

> Jesli w ogole SOAP, XSD i JAXB.

No właśnie, nie wiem :-)
A jak nie, to co dla smartnego klienta?

Pzdr. Wojtek

Andrzej Goławski

unread,
Nov 20, 2012, 1:43:46 PM11/20/12
to warsza...@googlegroups.com
> "Zdecydowane "nie" dla publikowania modelu, ktory sluzy tez do zapisu danych"

Tak z ciekawości .. dlaczego nie i czy zawsze nie ?

Pozdrawiam
 Andrzej

splatch

unread,
Nov 21, 2012, 7:51:40 AM11/21/12
to warsza...@googlegroups.com
Tak jak pisali poprzednicy - mappingi JPA załatwiasz sobie XML. Tak długo jak nie zacznie Ci się zmieniać model całość będzie działać.

Problemy zaczną się gdy model z XSD przestanie odzwierciedlać to co się dzieje w bazie. Model obiektowy nigdy nie jest wierną kopią modelu relacyjnego, zatem po zrobieniu proof of concept spróbuj zakombinować i zmienić model bez przewracania do góry nogami klienta. Opisywałem w sumie jak zrobić contract, client i server z CXF już parę lat temu:

W dniu wtorek, 20 listopada 2012 18:51:06 UTC+1 użytkownik Wojtek K napisał:
2012/11/20 Adam Lider <adam....@gmail.com>:
> Jesli koniecznie chcesz zestaw SOAP+XSD+JAXB to rozwaz podejscie gdzie
> definiujesz sobie interfejsy w WSDLu i XSDkach i z tego generujesz po
> stronie klienta i serwera interfejsy i klasy parametrow/wynikow. Jesli
> uzywasz mavena jest do tego plugin. Jesli Twoj model bedzie zblizony do klas
> interfejsu pomysl o bibliotece Dozer do mapowania pomiedzy tymi modelami. W
> innym przypadku "reczne" mapowania bardziej sie sprawdza. Zdecydowane "nie"
> dla publikowania modelu, ktory sluzy tez do zapisu danych.

Nie kręci mnie idea klepania wsdl'a i generowania kodu z tego. Po co
sobie życie utrudniać i grzebać się w wsdlu, skoro można to napisać w
naszym ulubionym języku? Choć, z tego co widzę, podejście top-down
jest często w javie promowane.
Dzięki za Dozera, ciekawe.
Jeżeli otwierasz się na zewnątrz i możesz mieć klienta który korzysta z innej biblioteki komunikacyjnej to wówczas klep XSD i WSDL. Dla mnie pisanie XSD, gdzie definiujesz typy jest tak na prawdę parę razy szybsze niż klepanie klas Javowych :) W prawdziwych integracyjnych rozwiązaniach nie masz web service'ów wystawionych na bazie deskryptora generowanego z adnotacji JAX-WS.
  
> Warto tez rozwazyc CXFa zamiast Metra.

Zgłębiam tajniki Java EE i na razie staram się trzymać standardu.
Podobno od wersji  6 EE daje się używać bez bólu, więc dlatego
patrzyłem na Metro. Widziałem, że wielu narzekało na axis od apache'a.
Czy CXF nie powiela jakichś upierdliwości tamtej biblioteki? W czym
jest lepszy od Metra? Współpracuje dobrze z WCF-em? W Metrze starają
się podobno o to dbać. 
Axis != CXF. To dwa różne światy. To tak jak postawienie C# i F# obok siebie. Obydwa są językami programowania, są z Microsoftu ale są zupełnie różne. Możesz korzystać z JAX-WS i CXF-a bez problemów. Warto zaznaczyć, że JBoss wykorzystuje tą samą bibliotekę u siebie do obsługi JEE.

 > Jesli w ogole SOAP, XSD i JAXB. 
No właśnie, nie wiem :-)
A jak nie, to co dla smartnego klienta?

WSDL ma to do siebie że określa interfejs. Możesz uzyskać podobny rezultat jeśli skorzystasz z WADL. Nie jest to w sumie tak bardzo rozpowszechnione, ale można na jego bazie chyba też generować klienta (głowy nie dam). Wówczas możesz sobie robić CXF z Jacksonem jako JAX-RS providerem i odpowiadać JSONem. :) 

Pozdrawiam,
Łukasz

Adam Lider

unread,
Nov 21, 2012, 10:21:11 AM11/21/12
to warsza...@googlegroups.com
Web service to nic innego jak API, ktore udostepniasz swiatu. Stworzenie dobrego API jest b. trudne, bo trzeba zrobic to tak, aby bylo spojne, latwe w uzyciu, utrzymywalne zapewniajac wsteczna kompatybilnosc jak najdluzej itp. Wiec nie widze mozliwosci, aby dodajac adnotacje JAXB do istniejacego modelu uzyskac namiastke dobrego API. Natomiast jesli uda nam sie uzyskac taki efekt, ze robimy kontrakt w WSDL+XSD, generujemy z tego interfejsy i model JAXB i probujemy jakos zamapowac to na baze danych to moze byc. Tylko watpie, zeby bylo to realne dla czegos poza helloworldem. 
Podkreslam, ze ja tutaj nie mowie o "fizycznej" mozliwosci zrobienia czegos, tylko o w miare poprawnym (w mojej ocenie) podejsciu. 

--
Adam Lider

ags

unread,
Nov 21, 2012, 10:28:44 AM11/21/12
to warsza...@googlegroups.com
2012/11/20 Wojtek K <wjt...@gmail.com>
Witam Wszystkich,
 
Zastanawiam się dodatkowo nad klasami encji. Sporo webservice'ów
powinno je w zasadzie używać 1-1, ale średnio mi się podoba
wystawianie w bibliotece współdzielonej między klienta i serwer jakieś
adnotacje JPA, pomieszane w dodatku z adnotacjami JAXB. Myślę nad
utworzeniem klas parametrów, które w wielu wypadkach różniłyby się
tylko brakiem adnotacji JPA.


Jak wielu, próbowałem jednego modelu do jpa i api. Da się, ale jest to później na tyle 
dramatycznie niewygodne, że wolę mówić "nie da się".

Rozpinaj i tnij, tak jak Ci koledzy mówią.

Jedyne w miarę ok miejsce gdzie mi to przeszło to był moduł to zdalnych EJBów - ale 
tam miałem kontrolę i autoupdaty, tylko domyślasz się, co było, gdy ktoś nie podniósł wersji ;-)

Adam Lider

unread,
Nov 21, 2012, 10:37:56 AM11/21/12
to warsza...@googlegroups.com
Jesli juz isc ta droga (SOAP,XSD,JAXB) to na calego i z podejsciem "contract first". Daje to wieksza kontrole i zrozumienie najwazniejszego elementem web serwisu czyli samego kontraktu. 
Ze swojej strony to polecam styl "document" oraz unikanie jak ognia wszelakiego rodzaju rozszerzen ws-*.
Co do samego CXF, to nie ma nic wspolnego z Axisem i z mojego doswiadczenia jest dojrzalym produktem godnym polecenia. Z Metrem nie mialem do czynienia.

Niestety natura SOAPa powoduje ze czesto to narzedzia i bilioteki oraz zwiazane z nimi problemy skupiaja nasza uwage bardziej niz dobry kontrakt (API). 

--
Adam Lider

Sławek Sobótka

unread,
Nov 21, 2012, 11:28:30 AM11/21/12
to warsza...@googlegroups.com
Rzecz nie jest w tym, że z WS wyciekają Ci adnotacje JPA.
Problemem jest to, że w API pojawia się wewnętrzny model domenowy implementacji. I mapowanie w XML nic nie pomoże:P
Jeżeli klienty widzą white box zamiast black box to zaczynają się wszystkie smutne historie, o których już koledzy pisali:)

Chyba, że na prawdę chodzi jedynie o zrobienie CRUDa... ale wszystkie opowieści o smokach zaczynają się zwykle tak samo: "dawno, dawno temu trzeba było na szybko zrobić CRUDa..."

Co do rozwiązania:
jakiś czas temu wyszła książka o projektowaniu API - autora już nie pamiętam; poszukaj dobrych praktyk SOA (generalnie chodzi o serwisy, nie koniecznie o web servisy na xmlu) oraz poszukaj info o modelu kanonicznym (w skrócie: to co znają klienta a model domeny w implementacji to dwa różne światy).


powodzenia

Sławek Sobótka

Marcin Burczak

unread,
Nov 21, 2012, 2:32:30 PM11/21/12
to warsza...@googlegroups.com
Generalnie najlepiej stosować podejście contract-first bo JAXB nie wspiera wszystkiego (przynajmniej tak mi się wydaje).
Jeśli chodzi o mapowania JPA/JAXB jest coś takiego jak Hyperjaxb3 generujący klasy Java z XSD z odpowiednimi adnotacjami, używałem tego ale teraz też sądzę że to nie był najlepszy pomysł (ale jak jest mało ludzi i ktoś sobie wymyśli zrzut komunikacji do bazy na jutro to może się przydać). Z generowanym kodem jest ten problem, że nie można w nim dodać własnej logiki chyba że zastosuje się jakiegoś visitora. Jak byś chciał to mam przykład konfiguracji plugina cxf-codegen-plugin.

Pozdrawiam,
Marcin

Wojtek K

unread,
Nov 22, 2012, 6:21:14 AM11/22/12
to warsza...@googlegroups.com
Dzięki za wszystkie odpowiedzi, sporo materiału do przemyśleń :-)
Sprawdziłem CXF, działa, wygląda dobrze, z metrem się komunikuje w
różnych konfiguracjach.

Wystawianie modelu do API faktycznie jest nie do obrony, widać sporo
kłopotów na horyzoncie. Ale jeszcze nie jestem do końca przekonany do
contract-first. Jeżeli wystawię bibliotekę z API, odseparowaną od
modelu, to myślę, że takie rozwiązanie chyba daję radę?

Trochę mnie przekonuje to, że CXF i Metro dają jednak inne wsdle, i
zmiana biblioteki mogłaby(?) ewentualnie spowodować zerwanie
kontraktu. Mój smartny klient raczej by tego nie odczuł, bo on
zmieniłby się analogicznie, ale zewnętrzne klienty już tak. W sumie i
migracja na nowa wersję biblioteki do WS mogłaby w nieszczęśliwym
przypadku zerwać kontrakt...

To jeszcze 2 pytania:
1) Stosujecie w wsdlu jakieś ograniczenia np. na długość
przekazywanych stringów, format stringa, zakres liczb? Czy po prostu
serwer opluwa jakimś znaczącym wyjątkiem? Tego chyba nie da się
osiągnąć w wsdlu w podejściu code-first i to by mnie dodatkowo
przekonało.

2) WS-*- nie, dlaczego?

Znalazłem taką książkę: http://www.servicedesignpatterns.com/

Pzdr. Wojtek

Jakub Nabrdalik

unread,
Nov 22, 2012, 6:40:45 AM11/22/12
to warsza...@googlegroups.com
On 22.11.2012 12:21, Wojtek K wrote:
> Wystawianie modelu do API faktycznie jest nie do obrony, widać sporo
> kłopotów na horyzoncie. Ale jeszcze nie jestem do końca przekonany do
> contract-first. Jeżeli wystawię bibliotekę z API, odseparowaną od
> modelu, to myślę, że takie rozwiązanie chyba daję radę?

Zanim robiłem WS w javie, robiłem WS w C#. W świecie .NETa
contract-first było rzadko spotykane. Robiłem code-first. Po kilku
miesiącach pieprzenia z nieczytelnym (generowanym) wsdl'em, ze zmianami
w postaci zamiana miejscami (numer linii) property w klasie C# i
rozpieprzenie z tego powodu komunikacji, nie byłem za specjalnie
zadowolony z tego rozwiązania. Mój jedyny argument przeciw code-first
był taki, że wsdle są obrzydliwe i nie chce mi się ich pisać ręcznie.

A potem zmieniłem technologię i kolega od Javy pokazał mi zajebiście
prostego, czystego wsdl'a, który nawet taka pała jak ja, jest w stanie
zrozumieć. I nagle okazało się, że moim głównym problemem były właśnie
biblioteki generujące wsdle, że łatwiej jest dobrze zdefiniować kontrakt
ręcznie, najpierw (zwłaszcze że myślisz o kontrakcie, a nie
implementacji pod spodem), niż robić code-first.

Później się co prawda okazało, że jeszcze przyjemniej jest zrobić
RESTfull JSON over HTTP, niż bawić w xml'a, więc WSDLe wystawiamy tylko
dla komunikacji zewnętrznej w korpo (czyli nie publicznej - tam gdzie
inni dostawcy jak nie dostaną kontraktu, to albo nakryją się nogami,
albo zaczną zrzucać na nas własny brak jakichkolwiek testów). Dla całej
reszty świata dobry JSON + przykłady, są zdecydowanie przyjemniejsze w
konsumpcji.


--
Jakub Nabrdalik
blog.solidcraft.eu

Wojtek K

unread,
Nov 22, 2012, 7:36:12 AM11/22/12
to warsza...@googlegroups.com
2012/11/22 Jakub Nabrdalik <jak...@gmail.com>:
> Zanim robiłem WS w javie, robiłem WS w C#. W świecie .NETa contract-first
> było rzadko spotykane. Robiłem code-first. Po kilku miesiącach pieprzenia z
> nieczytelnym (generowanym) wsdl'em, ze zmianami w postaci zamiana miejscami
> (numer linii) property w klasie C# i rozpieprzenie z tego powodu
> komunikacji, nie byłem za specjalnie zadowolony z tego rozwiązania. Mój
> jedyny argument przeciw code-first był taki, że wsdle są obrzydliwe i nie
> chce mi się ich pisać ręcznie.

:-) Dokładnie mój przypadek, pisałem ws w .net, z javą się nawet
komunikowaliśmy. O restach wtedy nikt z nas nie słyszał(choć w naszym
projekcie nie przeszłyby z powodów, o których napisałeś). A ilekroć
spojrzę w wsdl'a zbiera mnie na wymioty.

A jeżeli już trzeba zrobić wsdl, to jakie narzędzie byś polecił?
Edytor w eclipse jakoś mnie odrzuca, choć przyznaję, że za dużo się
nim nie bawiłem. W korpo używałem XMLSpy, całkiem ok, ale tani nie
jest.

Pzdr. Wojtek

Jakub Nabrdalik

unread,
Nov 22, 2012, 8:00:03 AM11/22/12
to warsza...@googlegroups.com
Ja niestety nie znam dobrego (też kiedyś miałem XMLSpy, a już nie mam).
Ktoś inny na grupie może coś polecić?


--
Jakub Nabrdalik
blog.solidcraft.eu

Mateusz Kaczmarek

unread,
Nov 22, 2012, 8:02:52 AM11/22/12
to warsza...@googlegroups.com
Ja polecam OxygenXML. Używałem jeszcze na studiach, gdy mieliśmy darmowe licencje i był bardzo przyjemny w obsłudze. Z tego co pamiętam miał wsparcie do klepania WSDL-i. Niestety drogi :/
Z kolei wykładowca lubił: http://www.altova.com/altovaxml.html, nie wiem czy słusznie.


Adam Lider

unread,
Nov 22, 2012, 12:48:23 PM11/22/12
to warsza...@googlegroups.com
On Nov 22, 2012, at 12:21 PM, Wojtek K <wjt...@gmail.com> wrote:

To jeszcze 2 pytania:
1) Stosujecie w wsdlu jakieś ograniczenia np. na długość
przekazywanych stringów, format stringa, zakres liczb? Czy po prostu
serwer opluwa jakimś znaczącym wyjątkiem? Tego chyba nie da się
osiągnąć w wsdlu w podejściu code-first i to by mnie dodatkowo
przekonało.

Sugeruje rozdzielic WSDLa od XSD w ten sposob, ze pierwszego uzywasz tylko do definiowania serwisu, operacji oraz wiadomosci wejscia/wyjscia. Natomist konkretne struktury danych definiujemy w XSDkach. WSDLe trzymajmy jak najmniejsze i zorientowane na jednej rzeczy, czyli definicji samego interfejsu. Mozna miec wiele WSDLi, kazdy dla innego modulu aplikacji. W XSDkach definiujesz sobie struktury danych i tutaj mozesz byc bardzo precyzyjnym, co, w jakiej kolejnosci i jakiej dziedziny ma byc. Walidacja, jak ja wlaczysz, zalatwi temat za Ciebie. Tylko czy tego na pewno potrzebujesz i co wiecej, czy to Ci bardziej pomoze czy zaszkodzi? Interfejs powinnismy tak zrobic, aby mozliwie bardzo ulatwic jego rozwoj bez zrywania kompatybilnosci. Trudna sztuka. Sa pewne wskazowki jak http://en.wikipedia.org/wiki/Robustness_principle ale i tutaj w pewnych warunkach podejscie calkiem odwrotne moze byc lepsze. 

2) WS-*- nie, dlaczego?

Tak zupelnie od tego nie uciekniesz. Np. bezpieczenstwo. Jesli robisz publiczne WSy, to b. prawdopodobne ze SSL bedzie potrzebny. Ale to nie oznacza ze od razu pelny ws-security z zaleznymi specyfikacjami nalezy aplikowac. W mojej opini te specyfikacjie opisuja czesto b. zlozne przypadki i co zatem idzie same sa zlozone, a ich implementacje skomplikowane i stosujac je bierzemy calosc.

--
Adam Lider

splatch

unread,
Nov 23, 2012, 8:14:09 AM11/23/12
to warsza...@googlegroups.com
Marcin,
Do JAXB możesz dopisywać tony kodu. Tu mały przykład jak dodać PropertyChangeSupport w JAXB http://blog.dywicki.pl/2007/11/28/rozszezanie-jaxb/.
Przyznam, że API do generowania jest nieco toporne, ale daje możliwość stworzenia nie tylko nowych klas ale również, dodania metod i pól do tych już "istniejących", tzn. stworzonych w domyślnym cyklu XJC.

Pozdrawiam,
Łukasz
Reply all
Reply to author
Forward
0 new messages