Newsgroup: it.comp.java
Titolo: Web service ed eccezioni

Salve a tutti,
Premetto che uso un application server jee 6 compatibile.
Lancio da un webservice delle eccezioni "checked" organizzate in una
gerarchia.
Semplifico (non ho compilato) il codice:
class A extends Exception{
}
class B extends A {
}
@Webservice
class WebService {
	public hello(String name) throws A {
 
		throw new B();
	}
}
Nel file wsdl autogenerato non c'è traccia di B ma solo di A.
Il tutto funzionerebbe se non fosse che l'eccezione B viene inglobata
in una SOAPFaultException.
In altri termini lato client (usamdo wsimport) l'eccezione B non appare
come sottoclasse di A.
Se lanciassi direttamente l'eccezione A tutto funzionerebbe come in una
tradizionale invocazione di metodo.
Se questa strada non è praticabile o non raccomandabile per qualche
ragione, mi piacerebbe sapere com conviene procedere.
Grazie per l'attenzione

 ragione, mi piacerebbe sapere com conviene procedere.
qualche considerazione:
l'esempio che hai fatto non è proprio significativo, a meno che hello
non faccia anche throw di C,D .. che estendono A, in ogni caso, poiché
il wsimport non va in tutti i figli di A, B non viene 'mappata'
se scrivi hello() throws B vedrai che viene mappata anche A.
Comunque sarebbe opportuno dichiarare in maniera esplicita tutte le
eccezioni sollevate da una action del servizio per queste ragioni:
1) rendere agevole la cattura lato consumer degli errori di servizio:
il manifest WSDL dichiara tutti i service fault possibili nel metodo
se sono esplicitati
2) nell'approccio WS si è soliti utilizzare il bottom-up (Java first),
questo tipo di approccio rende spesso e volentieri non utilizzabili i
servizi da altre tecnologie, che potrebbero utilizzare differenti tipi
di ereditarietà o addirittura non averne
3) l'ambiguità dei messages è fortemente sconsigliata, altrettanto dei
fault messages
Ti conviene scrivere il servizio come hai fatto ma fare il throw di B.
Chi genererà il client utilizzerà correttamente in Java le classi A e
B per accedere alle informazioni che gerarchicamente sono definite in
A, B.
Anche nel caso in cui hello possa sollevare più exceptions derivate da
A è corretto elencarle tutte.
Gianmarco

Grazie
Gianmarco Vanni ha scritto:


 di ereditarietà o addirittura non averne
non solo, ma in questo modo il contratto (wsdl) è conseguenza del codice 
per cui come tocchi il codice devi come minimo porre attenzione affinché 
lo schema non cambi, cosa non sempre da dare per scontata. per non 
parlare quando devi cambiare implementazione.

rootkit ha scritto:

Interessante. Allora si pone il problema di imparare a scrivere a "mano" 
il wsdl. Potresti consigliarmi un tutorial?


il wsdl non riesci a scriverlo a mano (facilmente e in maniera
corretta ed esaustiva) manco se sei il padreterno, se fai qualche cosa
di più complicato di helloworld (intendo se non sono servizi di
'test', ma cose singificative) usi uno dei meravigliosi editor che
esistono per esempio in Netbeans o in Eclipse, una volta lette le
raccomandazioni per il WSDL che puoi trovare ad esempio qui
http://www.w3.org/TR/wsdl
 per la v1
e qui
http://www.w3.org/TR/wsdl20/
 per la 2.
Fai molta attenzione perché a seconda di quale tecnologia per WS stai
utilizzando (e versione dell'engine) non è detto che la 2 sia
supportata.
In ogni caso, i WS si scrivono prima su carta, intendo dire un
servizio X, una azione per ogni operazione, un messaggio In e uno Out
e tutti gli eventuali fault.
Poi, aiutandoti con gli editor di cui parlavo prima, definisci gli
schema dei tipi di dato da utilizzare con i tuoi messages, e quindi
porta, servizio, binding e infine actions, vedrai che tutto viene
molto più semplice.
Fai particolare attenzione quando definisci i data Type a seguire le
raccomandazioni, utilizzando correttamente sequences e gli altri
attributi disponibili. Mappa un data Type con un element e l'element
con il messaggio, in questo modo, anche se all'inizio ti sembrerà una
tortura ti assicuri che modificando la definizione del dataType non
dovrai a buon bisogno toccare le interfacce dei servizi, eventualmente
rigenerare le classi che mappano il tipo (ma questo aspetto magari ti
può interessare solo se progetti WS per un gruppo di lavoro di quelli
che non gradiscono seguire le specifiche tecniche fornite o fanno un
po' come gli pare).
A questo punto genri gli stub di servizio che ti forniranno le classi
Java 'corrette' per i messaggi e le interfacce per le chiamate, ti
rimane solo l'implementazione della logica di ciascun servizio.
Se hai già la logica implementata ti è sufficiente mappare le tue
classi della business logic in quelle delle request e response dei
servizi, in maniera molto elementare (Y.set(X.get())  per lo più dove
Y è una classe di message e X una classe di business ad esempio).
In questo modo, dopo un po' di esperienza scrivi servizi che possono
poi essere veramente utilizzati da tutte le tecnologie che supportano
lo standard WS che hai scelto.
Gianmarco