I'm trying to implement simple web service client for PayPal Express Checkout API using JAX WS. PayPal Express Checkout API provides WSDL file, from which I was able to generate Java classes using CXF's wsdl2java utility.
From authentication reasons, it demands adding SOAP Header to each request. This header is quite simple and should look like here:
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECSOAPAPIBasics#id09C3I0CF0O6
Generated from WSDL classes include ebay.apis.eblbasecomponents.CustomSecurityHeaderType class which represents header which I need to add to each request.
So the question is: how can I add manually created instance of CustomSecurityHeaderType class to SOAP request's header taking into account following conditions:
- I'm not very eager to use classes from com.sun.* package as mentioned in answer here: JAX-WS – Adding SOAP Headers (mainly because of possible portability issues between different JDK's)
- I don't want to manually marshal that object into nested javax.xml.soap.SOAPElement instances as mentioned in answer here:
How do I add a SOAP Header using Java JAX-WS
Best Answer
So, it looks like I've found possible answer while combining JAX-WS & JAXB related answers from SO (I would really appreciate if somebody experienced in these technologies can check whether following is correct):
The obvious thing for me is to add SOAP message handler and alter header of SOAPMessage instance in it:
Explanation of bookmark #1: one should marshal not the header object itself, but JAXBElement representing that object, because otherwise one will get an exception. One should use one of ObjectFactory classes which are generated from WSDL for creating needed JAXBElement instances from original objects. (Thanks @skaffman for answer: No @XmlRootElement generated by JAXB )
One should also refer to
Martin Straus
answer which extends this one