title: How to change "SOAP-ENV" default prefix of Spring-WS
body: <p>I've created a web service using Spring-WS.
  To maintain compatibility with the old system, I need to change namespace prefix from <code>SOAP-ENV</code> to <code>soap</code>.</p>
  
  <p>I know that <code>SOAP-ENV</code> and <code>soap</code> are just namespace prefixes.
  As long as they refer to the correct namespace (<code>"http://schemas.xmlsoap.org/soap/envelope/"</code>), it should be fine.</p>
  
  <p>But the old system hard coded the parser code to expect only <code>soap</code> namespace prefix.</p>
  
  <p><strong>Current response:</strong></p>
  
  <pre><code>&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"&gt;
     &lt;SOAP-ENV:Header/&gt;
     &lt;SOAP-ENV:Body&gt;
     ...
     &lt;/SOAP-ENV:Body&gt;
  &lt;/SOAP-ENV:Envelope&gt;
  </code></pre>
  
  <p><strong>Expected response:</strong></p>
  
  <pre><code>&lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
     &lt;soap:Header/&gt;
     &lt;soap:Body&gt;
     ...
     &lt;/soap:Body&gt;
  &lt;/soap:Envelope&gt;
  </code></pre>
  
  <p><strong>Here's what I've tried so far</strong></p>
  
  <ol>
  <li><p>Create <code>EndpointInterceptorAdapter</code> subclass. This will intercept SOAP response/fault and alter the SOAP envelope.
  This works, but it's not ideal in terms of performance.</p>
  
  <pre><code>public class CustomEndpointInterceptor extends EndpointInterceptorAdapter {
  
    private static final String DEFAULT_NS = "xmlns:SOAP-ENV";
    private static final String SOAP_ENV_NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/";
    private static final String PREFERRED_PREFIX = "soap";
    private static final String HEADER_LOCAL_NAME = "Header";
    private static final String BODY_LOCAL_NAME = "Body";
    private static final String FAULT_LOCAL_NAME = "Fault";
  
    @Override
    public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
      SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
      alterSoapEnvelope(soapResponse);
      return super.handleResponse(messageContext, endpoint);
    }
  
    @Override
    public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
      SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
      alterSoapEnvelope(soapResponse);
      return super.handleFault(messageContext, endpoint);
    }
  
    private void alterSoapEnvelope(SaajSoapMessage soapResponse) {
      Document doc = soapResponse.getDocument();
      Element rootElement = doc.getDocumentElement();
      rootElement.setPrefix(PREFERRED_PREFIX);
      // Remove default SOAP namespace
      rootElement.removeAttribute(DEFAULT_NS);
      NodeList headerNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, HEADER_LOCAL_NAME);
      NodeList bodyNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, BODY_LOCAL_NAME);
      NodeList faultNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, FAULT_LOCAL_NAME);
      // Remove Header node.
      if (headerNodes.getLength() != 0) {
        rootElement.removeChild(headerNodes.item(0));
      }
      // Change Body's SOAP namespace prefix.
      if (bodyNodes.getLength() != 0) {
        Element bodyElement = (Element) bodyNodes.item(0);
        bodyElement.setPrefix(PREFERRED_PREFIX);
      }
      if (faultNodes.getLength() != 0) {
        Element faultElement = (Element) faultNodes.item(0);
        faultElement.setPrefix(PREFERRED_PREFIX);
      }
    }
  }
  </code></pre></li>
  <li><p>Change <code>package-info.java</code> in the package that contain WSDL generated classes.
  I've successfully done this with my company's namespace prefix, but it doesn't work for <code>SOAP-ENV</code> prefix.</p>
  
  <pre><code>@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.com/ns/2008/02/02/webservices/blah",
  xmlns = {
    @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://www.example.com/ns/2008/02/02/webservices/blah", prefix = ""),
    @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://schemas.example.com/ns/2007/10/blah", prefix = "ns2"),
    @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://example.com/ns/2007/23/05/blah/fundamental", prefix = "ns3"),
    @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://schemas.xmlsoap.org/soap/envelope/", prefix = "soap") // doesn't work
  },
  elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
  package com.thomsonreuters.ts.ets.interdayws.soap.webservice;
  </code></pre></li>
  </ol>
  
  <p>Is there an ideal way to change <code>SOAP-ENV</code> to <code>soap</code> in Spring-WS?</p>
  
  <p>By the way, here's the code that set this prefix.
  <a href="https://github.com/spring-projects/spring-ws/blob/2.2.2.RELEASE/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapElement.java#L47" rel="noreferrer">StroapElement.java</a></p>