79101435

Date: 2024-10-18 09:31:50
Score: 0.5
Natty:
Report link

Modify SOAP Prefix

CXF provides a property "soap.env.ns.map" to modify prefix of soap response.

import org.apache.cxf.binding.soap.Soap11;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

import java.util.HashMap;
import java.util.Map;


public class SoapResponsePrefixInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

    private String soapEnvelopePrefix;

    public SoapResponsePrefixInterceptor(String soapPrefix) {
        super(Phase.PREPARE_SEND);
        soapEnvelopePrefix = soapPrefix;
    }

    @Override
    public void handleMessage(SoapMessage message) {
        Map<String, String> envelopeNSMap = new HashMap<>();
        envelopeNSMap.put(soapEnvelopePrefix, Soap11.SOAP_NAMESPACE); // "http://schemas.xmlsoap.org/soap/envelope/"
        message.put("soap.env.ns.map", envelopeNSMap);
        message.put(AbstractOutDatabindingInterceptor.DISABLE_OUTPUTSTREAM_OPTIMIZATION, Boolean.TRUE);
    }
}

Include this class as an out interceptor, to modify the soap prefix.

SoapResponsePrefixInterceptor responsePrefixInterceptor = new SoapResponsePrefixInterceptor("soapenv");
factoryBean.getOutInterceptors().add(responsePrefixInterceptor);
factoryBean.getOutFaultInterceptors().add(responsePrefixInterceptor);

The logic for the same is implemented in SoapOutInterceptor.writeSoapEnvelopeStart(). hasAdditionalEnvNs() checks whether the application has configured any custom envelope name space and replace it with configured value.


Modify or remove namespace

CXF provides transformer feature that help us to modify namespace.

private Feature getTransformer() {
    StaxTransformFeature staxFeature = new StaxTransformFeature();
    Map<String, String> replaceElements = new HashMap<>();
    // value between braces is used as namespace, followed by localName.
    replaceElements.put('{' + DEFAULT_NAMESPACE + "}*", "");
    staxFeature.setOutTransformElements(replaceElements);
    staxFeature.setOutDefaultNamespace(DEFAULT_NAMESPACE);
    return staxFeature;
}

Add this transformer as a feature into the factory bean.

fb.setFeatures(List.of(getTransformer()));
  1. TransformOutInterceptor.createTransformWriterIfNeeded() - creates transformer if any of the values are set.
  2. RPCOutInterceptor.addOperationNode() > StaxUtils.writeStartElement() > OutTransformWriter.writeStartElement() > OutTransformWriter.write() - modifies the response based on the transformer.

logic for the same is present in OutTransformWriter() > TransformUtils.convertToQNamesMap() > DOMUtils.convertStringToQName()

Reasons:
  • RegEx Blacklisted phrase (1): help us
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Mathew Stephen