How to get SOAP headers

46,584

Solution 1

"[userId : null]" is generally the "toString" printout of a DOM element. Most likely if you do something like

logger.debug(header.getObject().getClass())

you will see that it is a DOM Element subclass of somesort. Thus, something like:

logger.debug(((Element)header.getObject()).getTextContent())

might print the text node.

Solution 2

    import javax.xml.soap.*;

    SOAPPart part = request.getSOAPPart();
    SOAPEnvelope env = part.getEnvelope();
    SOAPHeader header = env.getHeader();
    if (header == null) {
        // Throw an exception
     }

    NodeList userIdNode = header.getElementsByTagNameNS("*", "userId");
    String userId = userIdNode.item(0).getChildNodes().item(0).getNodeValue();

Solution 3

You can get soap headers without Interceptors and without JAXB.

In your service_impl class add :

public class YourFunctionNameImpl implements YourFunctionName{

@Resource
private WebServiceContext context;

private List<Header> getHeaders() {
    MessageContext messageContext = context.getMessageContext();
    if (messageContext == null || !(messageContext instanceof WrappedMessageContext)) {
        return null;
    }

    Message message = ((WrappedMessageContext) messageContext).getWrappedMessage();
    List<Header> headers = CastUtils.cast((List<?>) message.get(Header.HEADER_LIST));
    return headers;
}

...

Then in your function you can use:

List<Header> headers = getHeaders();
        for(Iterator<Header> i = headers.iterator(); i.hasNext();) { 
            Header h = i.next(); 
            Element n = (Element)h.getObject(); 

            System.out.println("header name="+n.getLocalName()); 
            System.out.println("header content="+n.getTextContent()); 
    }

Solution 4

We can get SOAP header in server side by adding following code in CXF interceptor.

Create a class like

public class ServerCustomHeaderInterceptor extends AbstractSoapInterceptor {

@Resource
private WebServiceContext context;

public ServerCustomHeaderInterceptor() {
    super(Phase.INVOKE);

}

@Override
public void handleMessage(SoapMessage message) throws Fault,JAXBException {
    System.out.println("ServerCustomHeaderInterceptor  handleMessage");
    JAXBContext jc=null;
    Unmarshaller unmarshaller=null;
    try {
    jc = JAXBContext.newInstance("org.example.hello_ws");
    unmarshaller = jc.createUnmarshaller();
    } catch (JAXBException e) {
    e.printStackTrace();
    }


    List<Header> list = message.getHeaders();
    for (Header header : list) {
            ElementNSImpl el = (ElementNSImpl) header.getObject();
        ParentNode pn= (ParentNode) el.getFirstChild();
        //Node n1= (Node) pn;
        //Node n1= (Node) el.getFirstChild();

        CustomHeader customHeader=(CustomHeader)  unmarshaller.unmarshal(el.getFirstChild());


    }

}

After this we need to inject this as a interceptor like

 <jaxws:inInterceptors>
        <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
    <bean class="org.example.hellows.soap12.ServerCustomHeaderInterceptor" />
   </jaxws:inInterceptors>

in your server context xml.

We may need to change few lines as per your requirements. Basic flow will work like this.

Share:
46,584
user219882
Author by

user219882

my about me is no longer blank

Updated on January 17, 2020

Comments

  • user219882
    user219882 over 4 years

    Here is the request

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:soap="http://soap.ws.server.wst.fit.cvut.cz/">
        <soapenv:Header>
            <userId>someId</userId>
        </soapenv:Header>
        <soapenv:Body>
        ...
        </soapenv:Body>
    </soapenv:Envelope>
    

    and I want to get that userId.

    I tried this

    private List<Header> getHeaders() {
        MessageContext messageContext = context.getMessageContext();
        if (messageContext == null || !(messageContext instanceof WrappedMessageContext)) {
            return null;
        }
        Message message = ((WrappedMessageContext) messageContext).getWrappedMessage();
        return CastUtils.cast((List<?>) message.get(Header.HEADER_LIST));
    }
    
    private String getHeader(String name) {
        List<Header> headers = getHeaders();
        if (headers != null) {
            for (Header header : headers) {
                logger.debug(header.getObject());
                // return header by the given name                   
            }
        }
        return null;
    }
    

    And it logs [userId : null]. How can I get the value and why is null there?

  • user219882
    user219882 about 12 years
    As I see it, HeaderList and JAXWSProperties are classes in com.sun.xml.internal.ws.* package. I really don't want to use this...
  • Kaliyug Antagonist
    Kaliyug Antagonist over 9 years
    Dunno how efficient and reliable this code snippet is but worked well for me ;)
  • burcakulug
    burcakulug almost 9 years
    this method was more convenient for me to access the SOAP headers from service layer. CXF FAQ: cxf.apache.org/faq.html#FAQ-HowcanIaddsoapheaderstothereques‌​t/…?
  • Tim Biegeleisen
    Tim Biegeleisen almost 9 years
    I found this answer helpful because it (correctly) shows how to extract things out of the SOAP header.
  • Nithil George
    Nithil George over 8 years
    SOAPPart part = request.getSOAPPart(); this part give me error, as it can't identify request.
  • kosgeinsky
    kosgeinsky about 8 years
    How do you obtain the request here?
  • Guillaume Polet
    Guillaume Polet almost 2 years
    MessageContext is part of the regular java packages, now