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="http://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="http://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 = "http://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 = "http://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;
    }

}

References

Download

You may also like...