• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Convert @WebService implemenation class into @WebServiceProvider implementation class

 
Himai Minh
Ranch Hand
Posts: 1360
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As I know, @WebService implementation class can have multiple arbitrary methods , but @WebServiceProvider implementation class can only have one invoke method inherited from Provider<T> interface.
Suppose I have this :


How to convert this implementation into @WebServiceProvider one ?
 
a sarkar
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@WebServiceProvider is not meant to operate on method level, it's supposed to be low level. I can think of a couple of things that you can do:

1. If you look at the generated WSDL for your @WebService endpoint, you'll see that each operation is uniquely identified by a SOAPAction URI. If you use the same in @WebServiceProvider invoke method to determine the intended "operation".
2. If you use MESSAGE mode, you can use your custom HTTP header to determine the intended "operation".
3. You can take the decision based on the payload as well. If you see an "add" element vs a "subtract" element, you know what the client is asking for.

Options 1 and 2 require that the client set the SOAPAction or HTTP header accordingly. Option 3 does not require the client to do that. However, purely from a design point of view, my personal preference would be option 1.

HTH.
 
Himai Minh
Ranch Hand
Posts: 1360
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks.
I have a further question for each option:
option 1. how can the @WebServiceProvider tell the intended operation from the Source request object in the above example?
option 2. when Service.Mode.MESSAGE is used, the Source request can be type cast to a DOMSource object. This DOMSource object is a SOAPMessage. From the SOAPMessage, we can see if it is an Add or the AddInteger or the subtract or multiply and etc.
option 3. when Service.Mode.PAYLOAD is used, the Source request is unmarshalled and type cast to JAXBElement. How can I tell if it is a JAXBElement<Add>, JAXBElement<Subtract>...
From Ivan's notes, here is an example of his StringProcessor:
 
a sarkar
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Himai Minh wrote:
option 1. how can the @WebServiceProvider tell the intended operation from the Source request object in the above example?

You either fish out the SOAPAction header from the Source or better, you don't use Source as the generic parameter, you use SOAPMessage as I show in an example below.


Himai Minh wrote:
option 2. when Service.Mode.MESSAGE is used, the Source request can be type cast to a DOMSource object. This DOMSource object is a SOAPMessage. From the SOAPMessage, we can see if it is an Add or the AddInteger or the subtract or multiply and etc.

I wouldn't cast Source to a DOMSource blindly. I'd check with instanceof operator and if not a DOMSource, transform to one if needed.
Himai Minh wrote:
option 3. when Service.Mode.PAYLOAD is used, the Source request is unmarshalled and type cast to JAXBElement. How can I tell if it is a JAXBElement<Add>, JAXBElement<Subtract>...

If you must use JAXB, you can use a JAXBElement<Operation> with the Operation class having a 'name' for the operation. Else, you can just parse the DOM tree and find out the name of the operation.
 
a sarkar
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It turns out that you can't overwrite standard HTTP headers once the dispatch has been created. So SOAPAction can't be used but a custom header can. In that case, option 1 and option 2 in my suggestion essentially become the same thing.
Out of curiosity, I wrote the code to test it out. You can find it here jaxws-provider.
 
Himai Minh
Ranch Hand
Posts: 1360
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your example.

If you must use JAXB, you can use a JAXBElement<Operation> with the Operation class having a 'name' for the operation.

In Ivan's notes, I tried to do this :

My intention is to do this:
 
a sarkar
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Himai Minh wrote:
My intention is to do this:


Can't do that due to Generics' type erasure. Try this instead:
 
Himai Minh
Ranch Hand
Posts: 1360
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, thanks for your advice. I changed Ivan's StringProcessor a little bit, it works.
In this case , I unmarshall the request and check if it is the right request object. If it is the right request object, do the work.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic