如何在发送请求时强制 JAXB 写入 javax.jws.WebParam 的 xsi:type(CXF 实现)
How to force JAXB to write the xsi:type of a javax.jws.WebParam when sending a request (CXF implementation)
我在 wsdl 上使用 wsdl2java 生成了 类,服务接口如下所示
@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
);
}
生成的请求是这样的
<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>
服务器(我无法以任何方式修改)拒绝抱怨缺少 MessaggioSII
元素的 xsi:type
的请求,并需要此语法
<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">
有没有办法强制CXF/JAXB写入xsi:type属性?
我已经查看了 cxf documentation 的转换,遗憾的是它不是很清楚。我宁愿不修改生成的 类 但我对此持开放态度。
作为解决方法,我添加了这个属性
@XmlAttribute(name = "type", namespace = XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI)
private String xsiType = "ns5:RichiestaSwitchingMessaggioSIIType";
它确实有效,但它特别脆弱,因为它依赖于我在构建时知道将生成的命名空间别名。
更好的方法是修改出站拦截器中的 soap 主体,请参阅 How To Modify The Raw XML message of an Outbound CXF Request?
或 howto modify a webservice request using CXF interceptors with org.w3c.dom.Node
顺便说一句,在服务中添加注解@SchemaValidation(type = SchemaValidationType.OUT)
似乎会导致客户端自动添加xsi:type 信息。卧槽
我在 wsdl 上使用 wsdl2java 生成了 类,服务接口如下所示
@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
);
}
生成的请求是这样的
<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>
服务器(我无法以任何方式修改)拒绝抱怨缺少 MessaggioSII
元素的 xsi:type
的请求,并需要此语法
<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">
有没有办法强制CXF/JAXB写入xsi:type属性? 我已经查看了 cxf documentation 的转换,遗憾的是它不是很清楚。我宁愿不修改生成的 类 但我对此持开放态度。
作为解决方法,我添加了这个属性
@XmlAttribute(name = "type", namespace = XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI)
private String xsiType = "ns5:RichiestaSwitchingMessaggioSIIType";
它确实有效,但它特别脆弱,因为它依赖于我在构建时知道将生成的命名空间别名。
更好的方法是修改出站拦截器中的 soap 主体,请参阅 How To Modify The Raw XML message of an Outbound CXF Request? 或 howto modify a webservice request using CXF interceptors with org.w3c.dom.Node
顺便说一句,在服务中添加注解@SchemaValidation(type = SchemaValidationType.OUT)
似乎会导致客户端自动添加xsi:type 信息。卧槽