javasoapjaxbcxf

How to force JAXB to write the xsi:type of a javax.jws.WebParam when sending a request (CXF implementation)


I've generated classes using wsdl2java on a wsdl, the service interface looks like this

@WebService(targetNamespace = "http://www.sii.example.it/SWG1", name = "SWG1")
@XmlSeeAlso({it.au.switchgas.swg1.messaggio.ObjectFactory.class, it.au.switchgas.swg1.strutturegenerali.ObjectFactory.class, it.au.switchgas.strutturegas.ObjectFactory.class, it.au.switchgas.swg1.flussi.ObjectFactory.class})
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface SWG1 {

    @WebMethod(operationName = "SWG1.0050", action = "SWG1.0050")
    @WebResult(name = "MessaggioSII", targetNamespace = "http://www.sii.example.it/SWG1", partName = "MessaggioSII")
    public it.au.switchgas.swg1.messaggio.AmmissibilitaRichiestaMessaggioSIIType swg10050(
        @WebParam(partName = "MessaggioSII", name = "MessaggioSII")
        it.au.switchgas.swg1.messaggio.RichiestaSwitchingMessaggioSIIType messaggioSII
    );
}

the generated request is like this

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ns1:SWG1.0050 xmlns:ns1="http://www.sii.example.it/SWG1">
            <MessaggioSII 
                xmlns:ns5="http://www.example.it/schemas/2010/SII_AU/MessaggioSII">
                    <ns5:RichiestaSII xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns5:RichiestaSwitchingRichiestaSIIType">
                    <ns5:AzioneRichiesta>
                        <ns5:Servizio>XYZ</ns5:Servizio>
                        <ns5:Operazione>ABC</ns5:Operazione>
                    </ns5:AzioneRichiesta>
                    <ns5:Erogatore>AXX</ns5:Erogatore>
                    <ns5:Fruitore>UXXXXX</ns5:Fruitore>
                </ns5:RichiestaSII>
                <ns5:DatiSII xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns5:RichiestaSwitchingDatiSIIType">
                </ns5:DatiSII>
            </MessaggioSII>
        </ns1:SWG1.0050>
    </soap:Body>
</soap:Envelope>

the server (which I can not modify in any way) rejects the requests complaining about the missing xsi:type of the MessaggioSII element and requires this syntax

<MessaggioSII xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns5:RichiestaSwitchingDatiSIIType"
xmlns:ns5="http://www.example.it/schemas/2010/SII_AU/MessaggioSII">

Is there any way to force CXF/JAXB to write the xsi:type attribute? I've looked at cxf documentation for transformations, sadly it's not very clear. I'd rather not modify the generated classes but I'm open to it.


Solution

  • as a workaround I've added this attribute

    @XmlAttribute(name = "type", namespace = XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI)
    private String xsiType = "ns5:RichiestaSwitchingMessaggioSIIType";
    

    which does work but it's especially fragile since it relies on me knowing at build time the namespace alias that will be generated.

    A better way would be modify the soap body in a outbound interceptor, see How To Modify The Raw XML message of an Outbound CXF Request? or howto modify a webservice request using CXF interceptors with org.w3c.dom.Node

    By the way, adding the annotation @SchemaValidation(type = SchemaValidationType.OUT) to the service seems to cause the client to add the xsi:type information automatically. WTF.