Spring WS Get Soap Header in Server
In the previous tutorial we added soap headers to the client using spring ws, in this example we show how to read and map the soap header on the server side. We use the @SoapHeader
annotation to map the Soap Header to a SoapHeaderElement
. This element contains the Soap Header which we can unmarshal using JAX-B.
Suppose we receive the following request.
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<auth:authentication xmlns:auth="https://memorynotfound.com/security">
<auth:username>username</auth:username>
<auth:password>password</auth:password>
</auth:authentication>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns2:getBeerRequest xmlns:ns2="https://memorynotfound.com/beer">
<ns2:id>1</ns2:id>
</ns2:getBeerRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
We create a simple POJO representing the Soap Header Element. This object will be used to unmarshal the Soap Header using JAX-B.
package com.memorynotfound;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(namespace = Authentication.AUTH_NS)
public class Authentication {
public static final String AUTH_NS = "https://memorynotfound.com/security";
@XmlElement(namespace = AUTH_NS)
private String username;
@XmlElement(namespace = AUTH_NS)
private String password;
public Authentication() {
}
public Authentication(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
We can extract the Soap Header on the server using the @SoapHeader
annotation and providing the QName
location URI of the resource we are trying to map. This gives us a SoapHeaderElement
which we can use to obtain the Source
document. We can pass this Source
to our JAX-B unmarshaller to unmarshal the source into a Authentiation
instance.
package com.memorynotfound.server;
import com.memorynotfound.beer.*;
import com.memorynotfound.client.Authentication;
import org.springframework.ws.server.endpoint.annotation.*;
import org.springframework.ws.soap.SoapHeaderElement;
import org.springframework.ws.soap.server.endpoint.annotation.SoapHeader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
@Endpoint
public class BeerEndpoint {
public static final String NAMESPACE_URI = "https://memorynotfound.com/beer";
@PayloadRoot(namespace = NAMESPACE_URI, localPart = "getBeerRequest")
@ResponsePayload
public GetBeerResponse getBeer(@RequestPayload GetBeerRequest request,
@SoapHeader("{" + Authentication.AUTH_NS + "}authentication") SoapHeaderElement auth) {
Authentication authentication = getAuthentication(auth);
// empty response
return new GetBeerResponse();
}
private Authentication getAuthentication(SoapHeaderElement header){
Authentication authentication = null;
try {
JAXBContext context = JAXBContext.newInstance(Authentication.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
authentication = (Authentication) unmarshaller.unmarshal(header.getSource());
} catch (JAXBException e) {
e.printStackTrace();
}
return authentication;
}
}