Search code examples
javaspringspring-bootsoapspring-ws

Retrieve custom header details from soap request developed using spring boot


I have developed soap request using spring boot where my soap request contain custom herders inside "" section of "soapenv:Header". I am facing issue to retrieve details passed inside "" section. There are no Exception but what I am receiving are all empty properties value of RequestHeader object at backend

My soap request looks like below:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://com/schema/OrderRequest" xmlns:ns="http://com/schema/RequestHeader">
   <soapenv:Header>
       <ns:RequestHeader>
        <ns:name>Name1</ns:name>
       </ns:RequestHeader>>
   </soapenv:Header>
   <soapenv:Body>
    .... no issue to retrieve body information
   </soapenv:Body>
 </soapenv:Envelope>

I an tring to retrieve header section using below code

@PayloadRoot(namespace = NAMESPACE_URI, localPart = "OrderRequest")
    @ResponsePayload
    public JAXBElement<OrderResponse> createOrder(@RequestPayload JAXBElement<OrderRequest>
            createWorkOrderRequestCplxType, @SoapHeader("{http://com/schema/RequestHeader/2/0}RequestHeader")SoapHeaderElement requestHeader) {

        log.info("Start createWorkOrder :");

    
        try{
            Source bodySource = requestHeader.getSource();
            DOMSource bodyDomSource = (DOMSource) bodySource;
            JAXBContext context = JAXBContext.newInstance(RequestHeader.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            RequestHeader requestH = (RequestHeader) unmarshaller.unmarshal(bodyDomSource);
            log.info("activity name from request header : {}",requestH.getName); //This value is getting empty
        }catch (JAXBException e){
            e.printStackTrace();
        
        }
  }

Can you please help me to understand what I am doing wrong?


Solution

  • I was tried multiple ways but didn't find direct solution to get Java object of RequesHeader directly in PayloadRoot method. Hence able to manage with below alternate approach:

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "OrderRequest")
        @ResponsePayload
        public JAXBElement<OrderResponse> createOrder(@RequestPayload JAXBElement<OrderRequest>
                createWorkOrderRequestCplxType, MessageContext messgeContext) {
    
            
            RequestHeader requestHeader = prepareRequestHeader(messageContext);
        
        
      }
      
      
      private RequestHeader prepareRequestHeader(MessageContext messageContext) {
       
        RequestHeader requestHeader = new RequestHeader();
        SoapHeader soapHeader = ((SoapMessage) messageContext.getRequest()).getSoapHeader();
        Iterator<?> elementIter = soapHeader.examineAllHeaderElements();
        while (elementIter.hasNext()) {
    
            Object element = elementIter.next();
            if (!(element instanceof SoapHeaderElement)) {
                continue;
            }
    
            Result result = ((SoapHeaderElement) element).getResult();
            if (!(result instanceof DOMResult)) {
                continue;
            }
    
            NodeList nodeList = ((DOMResult) result).getNode().getChildNodes();
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                if (node.hasChildNodes()) {
                    String nodeName = node.getNodeName();
                    String nodeValue = node.getFirstChild().getNodeValue();
                    addValueToRequestHeader(requestHeader, nodeName, nodeValue);
                }
            }
        }
        
        return requestHeader;
    }
    
    private void addValueToRequestHeader(RequestHeader requestHeader, String nodeName, String nodeValue) {
        log.info("Start addValueToRequestHeader for nodeName : {} and nodeValue : {}", nodeName, nodeValue);
        switch (nodeName) {
            case "ns:name":
                requestHeader.setActivityName(nodeValue);
                break;
            case "ns:lastname":
                if (nodeValue.equalsIgnoreCase(RequestMessageType.NOTIFICATION.value())) {
                    requestHeader.setMsgType(RequestMessageType.NOTIFICATION);
                } else {
                    requestHeader.setMsgType(RequestMessageType.REQUEST);
                }
                break;
            case "ns:middlename":
                requestHeader.setSenderURI(nodeValue);
                break;   
            default:
                break;
        }
     
    }