Skip to main content

Working with SOAP service headers

How to modify headers in the SOAP response.


Below snippet will do the trick. In a nutshell, you need to:
  • Add @SoapHeader annotation in the service method.
  • Use Unmarshaller to map header xml elements to java object.
  • Make necessary changes to this java object.
  • Finally, use Marshaller to map java object back to xml, and set in response.

// Service class code


private static final String NAMESPACE_URI = "http://domain.com/context/../DummyRequest.xsd";

@PayloadRoot(namespace = NAMESPACE_URI, localPart = "RequestPartInXml")
@ResponsePayload
public JAXBElement<ResponsePOJO> returnApiResponse(
@RequestPayload JAXBElement<RequestPojo> request,
@SoapHeader(value = "{http://domain.com/context/../DummyRequest.xsd}MessageHeader") SoapHeaderElement soapHeaders,
MessageContext messageContext) {

// handleSoap Headers
handleSoapHeaders(messageContext, soapHeaders);

...
...

}
// handling of headers
public static void handleSoapHeaders(MessageContext messageContext, SoapHeaderElement soapHeaders) {
try {
context = JAXBContext.newInstance(ObjectFactory.class);
MessageHeaderInfo requestSoapHeaders = getRequestHeaders(soapHeaders);
setCustomHeaders(requestSoapHeaders);
pushResponseHeaders(messageContext, requestSoapHeaders);
} catch (JAXBException e) {
e.printStackTrace();
}
}
// Use un-marshalling to map Xml to Java Object
private static MessageHeaderInfo getRequestHeaders(SoapHeaderElement soapHeaders) throws JAXBException {
Unmarshaller unmarshaller = context.createUnmarshaller();
JAXBElement<MessageHeaderPojo> headers = (JAXBElement<MessageHeaderPojo>) unmarshaller
.unmarshal(soapHeaders.getSource());
return headers.getValue();
}

private static void setCustomHeaders(MessageHeaderPojo requestSoapHeaders) {
MessageHeaderPojo mH = requestSoapHeaders;
mh.setOneObj(requestSoapHeaders.getOneObj()); // to return request Header Element as it is in the response
mh.setSecondObj(requestSoapHeaders.getSecondObj());
mh.setThirdObj(requestSoapHeaders.getThirdObj()); // to modify request Header Object and send in response
mh.getThirdObj().setnewParameter("customValue"); // newParameter is an attribute in ThirdObj Class
}

// Use marshalling to map Java back to Xml
private static void pushResponseHeaders(MessageContext messageContext, MessageHeaderPojo mh)
throws JAXBException {
ObjectFactory obja = new ObjectFactory();
JAXBElement<MessageHeaderPojo> modifiedHeaders = obja.createMessageHeader(info);
Marshaller marshaller = context.createMarshaller();
SaajSoapMessage soapResponses = (SaajSoapMessage) messageContext.getResponse();
SoapHeader resheader = soapResponses.getSoapHeader();
marshaller.marshal(modifiedHeaders, resheader.getResult());
}



If any issues are encountered, do drop the same in comments section.
I will be happy to help.

######### Happy Coding #########

Comments

Popular posts from this blog

Add/Modify Header Values in Java HttpServletRequest using Servlet Filters

Add/Modify Header Values in Java HttpServletRequest using Servlet Filters Steps to Modify Request Headers in a Servlet Request. This example will demonstrate how to modify 'Content-Type' header in Java Servlet Filter. In order to achieve this, use a custom wrapper Class, that extends HttpServletRequestWrapper. Thereafter, we need to override certain methods inside this custom Class. getHeader(String name) getHeaders(String name) getHeaderNames() getParameter(final String name) Code snippet for overriding above methods.     @Override     public String getHeader(String name) {     String header = super.getHeader(name); if ("content-type".equalsIgnoreCase(name)){ System.out.println("Adds Header Content-Type as application/json"); return "application/json"; }         return header;     }          @Override     public Enumeration ...

Fixing Keycloak Error : MediaType not set on path , with response status 200

Using a custom endpoint with Media Type set as 'Application/Json'. When this endpoint is accessed, below error is returned. ERROR [org.keycloak.headers.DefaultSecurityHeadersProvider] (default task-16) MediaType not set on path /auth/realms/my-realm/broker/keycloak-oidc/token, with response status 200 06:31:08,489 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-16) Uncaught server error: javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error at org.keycloak.keycloak-services@10.0.2//org.keycloak.headers.DefaultSecurityHeadersProvider.addHeaders(DefaultSecurityHeadersProvider.java:71) at org.keycloak.keycloak-services@10.0.2//org.keycloak.services.filters.KeycloakSecurityHeadersFilter.filter(KeycloakSecurityHeadersFilter.java:36) The fix for this is to bind the blank response to Application/Json as follows: return Response.ok(json, MediaType.APPLICATION_JSON).build(); Do try it out, and let me know if it works. Do drop some comments is an...

Run Spring Boot application in Standalone Tomcat Server

How to run Spring Boot application on Tomcat To deploy a Spring Boot application on existing Tomcat Server, or to bundle it as war file and deploy on Tomcat, following changes are required: Change to war packaging in pom.xml: <packaging>war Application Main class to extend  SpringBootServletInitializer. Override configure method in this class.                protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {                        return application.sources(Application.class);                } Add Tomcat-starter dependency in pom.xml. <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-tomcat</artifactId>     <scope>provided</scope> </dependency...