There's really three ways to do this:

1) Grab the XMLStreamReader from the message, use something to convert it to a 
DOM (not too hard, our staxutils and such can do it), manipulate the DOM, wrap 
with a new XMLStreamReader and replace in the message.

2) Similar to (1), add the SAAJInInterceptor to the chain.   That will convert 
the message to an SAAJ model.   Add your own interceptor that would then take 
that saaj model and manipulate it.   

Higher performing method, but more complex:
3) Take the XMLStreamReader from the message and wrapper it with a new 
XMLStreamReader (you can use javax.xml.stream.util.StreamReaderDelegate as a 
base class to handle much of that).    Override the calls to getName(), (to 
record the current element name) getElementText(), getText(), 
getTextCharacters(), etc....  to "track" what is being read.    If the element 
path is one that you need to verify, verify the resulting text before 
returning it.     This avoids building the DOM and such which would result in 
better performance and allows the streaming to continue and such.   However, 
the "tracking" and such is definitely a bit more complex.

Dan



On Sun April 26 2009 8:51:14 am bartimaeus wrote:
> In the application that I am working for my client, soap message is passed
> as input to a web service method which accepts a Java bean as an argument.
> The mapping from the xml input to Java Bean is being handled by Apache CXF
> which is internally using JAXB for unmarshalling.
>
> The application requires incorrect input data to get replaced by some
> default value. For eg, if the web service method accepts PersonBean as
> argument, the XML input would have elements like name, age etc. Now, if the
> age field in the input comes in as anything other than a number, the value
> to set in the bean should be a default one specified for it (this may sound
> strange, but it is for an EAI project and this is what the client wants)
>
> To achieve this without disturbing the architecture in place, I created my
> own custom CXF interceptor and placed it before the interceptor which
> unmarshalls the input data in the interceptor chain. Thus I was able to
> catch the exception when incorrect data was encountered. But, I was not
> able to find a way to replace the incorrect data with default values. The
> Message reference passed to the interceptor seems to provide only read-only
> access to the input XML. I am sorry that I am not supposed to post the
> actual code here. The custom interceptor that I have developed looks
> something like this –
>
>    1. public class CustomInterceptor extends
> AbstractPhaseInterceptor<Message> {
>    2.     public CustomInterceptor() {
>    3.         super(Phase.UNMARSHAL );
>    4.     }
>    5.
>    6.     public void handleMessage(Message message) {
>    7.        // Code to validate message and modify message.
>    8.     }
>    9. }
>
> So guys, please suggest me your opinions on this. It would be great if
> anyone here can suggest a way to modify the data wrapped in the message
> reference passed to the handleMessage method shown above. It would also be
> good to know about other ways to resolve my problem.

-- 
Daniel Kulp
[email protected]
http://www.dankulp.com/blog

Reply via email to