What is a soap header ?
From w3schools:
I decided to extend my wsdl first example to try the same.
The first step was to define a header in the xsd:
Executing a wsdl2java command on the xsd resulted in a simple RandomHeader class.
The next step was to modify the server endpoint to add the header to the request.
As I was working with the JAX WS interfaces (or JAXWS frontend), I used the WebServiceContext class:
I looked up the WebServiceContext interface:
From w3schools:
The optional SOAP Header element contains application-specific information (like authentication, payment, etc) about the SOAP message. If the Header element is present, it must be the first child element of the Envelope element. All immediate child elements of the Header element must be namespace-qualified.So the soap message would be something like :
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <!-- The header elements --> </soap:Header> <soap:Body> <!-- The body elements --> </soap:Body> </soap:Envelope>I have never had to use headers in my code. Until recently. While working with CXF, I was needed to add a soap header for the response.
I decided to extend my wsdl first example to try the same.
The first step was to define a header in the xsd:
<xs:element name="RandomHeader"> <xs:complexType> <xs:all> <xs:element name="hostName" type="xs:string" maxOccurs="1" minOccurs="1" /> </xs:all> </xs:complexType> </xs:element>This is just a normal element.
Executing a wsdl2java command on the xsd resulted in a simple RandomHeader class.
The next step was to modify the server endpoint to add the header to the request.
As I was working with the JAX WS interfaces (or JAXWS frontend), I used the WebServiceContext class:
private static final QName HEADER_QNAME = new QName("http://ws.com/Service/xsd/random-schema", "RandomHeader"); @Autowired private WebServiceContext wsContext; private void addNameHeader() throws JAXBException { final RandomHeader rHeader = new RandomHeader(); rHeader.setHostName("WhoCares !!"); // will be specific to each thread/ request final MessageContext messageContext = this.wsContext.getMessageContext(); final List<Header> headers = new ArrayList<Header>(); headers.add(new Header(HEADER_QNAME, rHeader, new JAXBDataBinding(RandomHeader.class))); messageContext.put(Header.HEADER_LIST, headers); } @Override public GetRandomResponse random(final GetRandomRequest getRandomRequest) { LOG.info("Executing operation random"); System.out.println(getRandomRequest); try { this.addNameHeader(); final GetRandomResponse _return = new GetRandomResponse(); _return.setValue((int) (Math.random() * 175)); return _return; } catch (final java.lang.Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } }The WebServiceContext was a bean injected into the class:
<bean id="wsContext" class="org.apache.cxf.jaxws.context.WebServiceContextImpl"/>The WebServiceContext is a JAXWS interface which we have injected with a CXF implementation. The code involved the following steps:
- Get a reference to the MessageContext - which is nothing but a map of key value pairs.
- To this map we add a list of header objects.
- When this response is translated to SOAP, all the headers in the list are written to the SOAP header element.
I looked up the WebServiceContext interface:
WebServiceContext makes it possible for a web service endpoint implementation class to access message context and security information relative to a request being servedThe interface indicates that the message context is :
- Associated with a request ant not a response.
- A different and unique message context must be bound to every request object. When a response to this request is needed to be returned, the data from the message context is written to the response.
public class WebServiceContextImpl implements WebServiceContext { private static ThreadLocal<MessageContext> context = new ThreadLocal<MessageContext>(); private final MessageContext localCtx; public WebServiceContextImpl() { localCtx = null; } public WebServiceContextImpl(MessageContext c) { localCtx = c; } // Implementation of javax.xml.ws.WebServiceContext public final MessageContext getMessageContext() { return localCtx == null ? context.get() : localCtx; } // ... remaining code }If I were to make a call to the webservice then the response is:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <RandomHeader xmlns="http://ws.com/Service/xsd/randomschema"> <hostName>WhoCares !!</hostName> </RandomHeader> </soap:Header> <soap:Body> <GetRandomResponse xmlns="http://ws.com/Service/xsd/randomschema"> <value>73</value> </GetRandomResponse> </soap:Body> </soap:Envelope>
No comments:
Post a Comment