• Post Reply Bookmark Topic Watch Topic
  • New Topic

How to add pre-existing xml fragments to SOAP response being built with JAX-WS generated classes

 
Tex Martin
Greenhorn
Posts: 10
1
Eclipse IDE IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Howdy Ranchers :-)
I am building a SOAP web service, contract first.
I have made a WSDL and I have generated a folder full of java classes using WSImport
I have made an implementation of the PortType which was generated as part of the WSImport
This implementation, I am packaging along with other classes and supporting files in a WAR which is deployed on a Jetty server
This is all working well and fine.

Recently - I have added a new webservice method (wsdl operation) along the lines of the ones I have already, and I can generate the resulting WSImport classes.
So far so good...

Now - I just realised that I have pre-existing xml fragments ready to stitch inside the response, instead of parsing the fragments and use the resulting information as parameters, when calling methods on the WSImport generated classes.
So - In other words, I would like to use the xml fragments as they are, and include them in the SOAP response, instead of recreating the same xml structure, and content, by calling methods on the generated classes.

I have of course tried to search the web for examples, tutorials, or answers - but unfortunately with no mentionable luck. The best hits I got was concerning SAAJ. As far as I can tell, SAAJ is probably not the right path to follow, in this case.

I would be very happy, if any of you could point me in the right direction.

Thanks in advance.
 
Karthik Shiraly
Bartender
Posts: 1210
25
Android C++ Java Linux PHP Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The usual way to do this would be to implement a document style WS and pass XML fragments as response. But, since you want to avoid the parse XML -> to Object-> to SOAP XML conversion steps and instead use pre-existing XML fragments directly, that approach can't be used.

A WSDL, example of a pre-existing XML and a sample request-response captured using soapui, might help come up with a correct answer.

In their absence, one approach I can think of is using a JAX-WS LogicalHandlers.

This approach requires some assumptions I've to make in the absence of a WSDL or request-response:
1. That you are already using, or can change, to a Document style web service.
2. That these pre-existing XML fragments conform to the port's output schema declared in the WSDL.

If these assumptions are true, then steps are:
1. Create a logical handler implementation like this example.

2. In handleMessage(), load the correct pre-existing XML into a Document and set it as payload for outgoing messages (i.e., responses) instead of the default JAX-WS created payload.


3. Create a handler chain XML and annotate your service impl class with it as shown in this example.

4. Normally your port's implementation would return some properly constructed object. Instead, return null. The handler will then inject the pre-existing XML into the SOAP response on its way out.
 
Tex Martin
Greenhorn
Posts: 10
1
Eclipse IDE IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Karthik
Thank you very much for pushing me in the direction of SOAPHandler/LogicalHandler
Both of your assumptions are correct - I was using Document Style web service already, even though it wasn't an informed, deliberate choice :-)

I had some trouble selecting a good spot in my project folder structure for the handler chain XML configuration file - Well, selecting the spot was not so hard, finding it again in the @HandlerChain annotation was the hard part ;-)
I ended up having it in src/main/resources and finding it again with file="handler-chain.xml"

Some moments ago I realised that I will have to discriminate which of my webservice methods was called, before considering modifying the response - only one of my methods will have its response built this way...
My idea is to check the value of the SOAPAction header, to make sure that the response is only modified when it's relevant.

Next, I will have to figure out how to modify the response, and not the least; how to stitch the correct xml fragments into the response - in this matter my idea is to either let the SOAPHandler access the DB using a Dao or let the webservice implementation class deliver the fragments in some kind of context variable.

I'll keep you posted...

 
Karthik Shiraly
Bartender
Posts: 1210
25
Android C++ Java Linux PHP Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, as you've already figured out, the final implementation is not going to be anywhere as simple as that code snippet I've posted.

Though it's a possible approach, personally I felt it was something of a hack while writing it and hesitated a bit before posting.
I was imagining a maintainer dev some years down the line wondering why this web service implementation does nothing at all and returns null for every request .
The proper use for logical handlers is as decorators - adding some aspects external to the core payload, perhaps things like authentication or encryption. Replacing the payload entirely is rather odd.
Out of curiosity, why do you prefer this approach?
 
Tex Martin
Greenhorn
Posts: 10
1
Eclipse IDE IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry for taking so long to return to this topic...
I made a solution that modifies the response along the lines sketched out earlier;
In the @Webservice' relevant @Webmethod i put a map of the xml fragments in the messageContext, and return a partial response

In a SOAPHandler i detect that the response is from the relevant @Webmethod and modify the response, using the xml fragments stored in the messageContext earlier.
It was a challenge to stitch the partial response xml document together with the xml fragment documents - this stackoverflow Q/A was very helpful in that respect: http://stackoverflow.com/questions/883987/java-appending-xml-docs-to-existing-docs

Right now, I'm at a stage where I have to decide how to change the state of the rows in the database, from which I retrieved the xml fragments (to signal, that they have been successfully sent, to the webservice client). It feels wrong to let the SOAPHandler do this.

I am as sceptical towards this solution as you are, and for the same reasons. Heck - the maintainer you mention could even be myself :-)
As an alternative, I am exploring a JAXB XmlAdapter approach. I Will provide more info on this, as and when I make it work.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!