Add HTTP Headers To SOAP Request Using CXF

Add HTTP Headers to a SOAP Request Using CXF explains about step by step details of setting custom http headers to a SOAP Request and retrieve the headers in server side by using CXF.

Message message = PhaseInterceptorChain.getCurrentMessage();
SoapMessage soapMessage = (SoapMessage) message;
List list = soapMessage.getHeaders(); 
for (Header header : list) { 
  System.out.println("Country: "+((Element)header.getObject()).getTextContent()); 
}

On above code, we are getting list of header from SoapMessage

Note

You can also use cxf interceptor in order to add HTTP Headers to a SOAP Request, see more about CXF Interceptors below.

1) http://cxf.apache.org/faq.html#FAQ-HowcanIaddsoapheaderstotherequest%2Fresponse%3F
2) http://cxf.547215.n5.nabble.com/Adding-SOAPHeader-using-an-Interceptor-td567851.html
3) CXF Interceptor Example

Required Libraries

You need to download

  1. OpenJDK 8 / Corretto
  2. Eclipse 4.15
  3. CXF-3.3.6
  4. Tomcat 9

Following jar must be in classpath

  1. cxf-core-3.3.6.jar
  2. cxf-rt-bindings-soap-3.3.6.jar
  3. cxf-rt-databinding-jaxb-3.3.6.jar
  4. cxf-rt-features-logging-3.3.6.jar
  5. cxf-rt-frontend-jaxws-3.3.6.jar
  6. cxf-rt-frontend-simple-3.3.6.jar
  7. cxf-rt-transports-http-3.3.6.jar
  8. cxf-rt-wsdl-3.3.6.jar
  9. httpasyncclient-4.1.4.jar
  10. httpclient-4.5.12.jar
  11. httpcore-4.4.13.jar
  12. httpcore-nio-4.4.13.jar
  13. neethi-3.1.1.jar
  14. slf4j-api-1.7.29.jar
  15. slf4j-jdk14-1.7.29.jar
  16. spring-aop-5.1.14.RELEASE.jar
  17. spring-beans-5.1.14.RELEASE.jar
  18. spring-context-5.1.14.RELEASE.jar
  19. spring-core-5.1.14.RELEASE.jar
  20. spring-expression-5.1.14.RELEASE.jar
  21. spring-jcl-5.1.14.RELEASE.jar
  22. spring-web-5.1.14.RELEASE.jar
  23. stax2-api-3.1.4.jar
  24. woodstox-core-5.0.3.jar
  25. wsdl4j-1.6.3.jar
  26. xmlschema-core-2.2.5.jar

Add Custom HTTP Headers To SOAP Request Using CXF

I am creating a sample web service project that pass Student object and return with some changes on that object. The service is using simple POJO (Plain Old Java Object) bean.

Firstly create a Dynamic Web Project (File->New->Dynamic Web Project) named "CXFTutorial" according to following screenshot

Create CXF Project CXF Tutorial

Create a Student Object

package com.student;

public class Student {
 
private String name;
 
public String getName() {
   
return name;
 
}
 
public void setName(String name) {
   
this.name = name;
 
}
}

Create a Service Interface

This service interface will defines which methods of web service, to be invoked by the client

package com.student;

import javax.jws.WebService;

@WebService
public interface ChangeStudentDetails {
 
Student changeName(Student student);
}

Implement the Service Interface

Here we implement the service interface created on the previous step

package com.student;

import java.util.List;
import javax.jws.WebService;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.w3c.dom.Element;

@WebService(endpointInterface = "com.student.ChangeStudentDetails")
public class ChangeStudentDetailsImpl implements ChangeStudentDetails {
   
public Student changeName(Student student) {

       
Message message = PhaseInterceptorChain.getCurrentMessage();

        SoapMessage soapMessage =
(SoapMessage) message;
        List<Header> list = soapMessage.getHeaders
();
       
for (Header header : list) {
           
System.out.println("Country: "+((Element)header.getObject()).getTextContent());
       
}
      
       
student.setName("Hello " + student.getName());
       
return student;
   
}
}

Create a cxf.xml

CXF is using Spring internally, Finding classes by spring we need to add service implementation class on "jaxws:endpoint" tag

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:cxf="http://cxf.apache.org/core"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd  
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
	<bean class="org.apache.cxf.ext.logging.LoggingInInterceptor" id="logInInterceptor" />
	<bean class="org.apache.cxf.ext.logging.LoggingOutInterceptor" id="logOutInterceptor" />
	<cxf:bus>
		<cxf:inInterceptors>
			<ref bean="logInInterceptor" />
		</cxf:inInterceptors>
		<cxf:outInterceptors>
			<ref bean="logOutInterceptor" />
		</cxf:outInterceptors>
	</cxf:bus>
	<jaxws:endpoint id="changeStudent" implementor="com.student.ChangeStudentDetailsImpl"
		address="/ChangeStudent" />
</beans>

Change web.xml

Change the web.xml file to find CXF servlet and cxf.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/cxf.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

Publishing CXF Web Service

Run CXF On Tomcat

Note

You can Find all the deployed JAX-WS/JAX-RS services you need to append 'services' at the end of the URL so URL will become following

http://localhost:8080/CXFTutorial/services

Deployed CXF Web Service

CXF WebService Running

Run

You can also use wsimport tool for testing this service. Only thing need to change is modify the Main class according to below class

package com.client;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.student.ChangeStudentDetails;
import com.student.ChangeStudentDetailsImplService;
import com.student.Student;

import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;

import org.apache.cxf.headers.Header;
import org.apache.cxf.jaxb.JAXBDataBinding;


//How To Add HTTP Headers to a SOAP Request Using CXF
public class Main {
   
   
public static void main(String[] args) throws JAXBException {
       
ChangeStudentDetailsImplService service = new ChangeStudentDetailsImplService();
        ChangeStudentDetails changeStudentDetailsImplPort = service.getChangeStudentDetailsImplPort
();

        List<Header> headers =
new ArrayList<Header>();
        Header soapHeader =
new Header(new QName("Country"), "India",new JAXBDataBinding(String.class));
        headers.add
(soapHeader);

        Map<String, Object> ctx =
((BindingProvider) changeStudentDetailsImplPort)
               
.getRequestContext();
        ctx.put
(Header.HEADER_LIST, headers);

        Student student =
new Student();
        student.setName
("Rockey");
        student = changeStudentDetailsImplPort.changeName
(student);
        System.out.println
(student.getName());

   
}

}
Output (Tomcat Console)

Below console you can see that http soap header is appended with the request (key->Country and value->India) and it is displaying in the Tomcat console.

ID: 2
Address: http://localhost:8080/CXFTutorial/ChangeStudent
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[257], content-type=[text/xml; charset=UTF-8], host=[localhost:8080], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 2.7.12]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><Country>India</Country></soap:Header><soap:Body><ns2:changeName xmlns:ns2="http://student.com/"><arg0><name>Rockey</name></arg0></ns2:changeName></soap:Body></soap:Envelope>
--------------------------------------
Country: India
Oct 21, 2014 9:08:46 AM org.apache.cxf.services.ChangeStudentDetailsImplService.ChangeStudentDetailsImplPort.ChangeStudentDetails
INFO: Outbound Message
---------------------------
ID: 2
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:changeNameResponse xmlns:ns2="http://student.com/"><return><name>Hello Rockey</name></return></ns2:changeNameResponse></soap:Body></soap:Envelope>
--------------------------------------










1 Responses to "Add HTTP Headers To SOAP Request Using CXF"
  1. mirec 2021-11-12 23:00:43.0

Your email address will not be published. Required fields are marked *