Java 如何注入;“一网打尽”;xsd:WSDL描述的每个响应对象中有任何元素吗?
我们有一个由C#和Java客户端使用的SOAP Web服务 问题在于,当我们升级Web服务时,客户端并不急于重新生成其代理,因此为旧版本生成的代理代码可能会用于使用新版本的服务 很可能,向响应对象添加新属性会破坏使用已经生成的旧代理代码的Java客户机。显然,Java对WSDL的解释非常严格,当WSDL中不存在的属性到达时,会出现异常而失败。至少,这是我们观察到的ApacheAxis生成的代理代码。C#客户很好——新的属性被忽略了 我正在想办法解决这个问题。一个似乎可行的解决方案是将Java 如何注入;“一网打尽”;xsd:WSDL描述的每个响应对象中有任何元素吗?,java,wcf,soap,xsd,wsdl,Java,Wcf,Soap,Xsd,Wsdl,我们有一个由C#和Java客户端使用的SOAP Web服务 问题在于,当我们升级Web服务时,客户端并不急于重新生成其代理,因此为旧版本生成的代理代码可能会用于使用新版本的服务 很可能,向响应对象添加新属性会破坏使用已经生成的旧代理代码的Java客户机。显然,Java对WSDL的解释非常严格,当WSDL中不存在的属性到达时,会出现异常而失败。至少,这是我们观察到的ApacheAxis生成的代理代码。C#客户很好——新的属性被忽略了 我正在想办法解决这个问题。一个似乎可行的解决方案是将xsd:an
xsd:any
属性注入到WSDL中找到的每个响应对象中。据我所知,各种Java实现将使用它作为所有未知属性的“一网打尽”属性(当然,客户机将不得不重新生成其代理以使用这些xsd:any定义,但一旦完成,新属性将抓住以破坏其代码)
问题是如何在WSDL中注入这些xsd:any
属性,而不向响应对象实际添加真正的“catch all”属性
我们的Web服务是使用WCF实现的。显然,实现它的唯一方法是引入一个新的端点行为,它还实现了
IWsdlExportExtension
接口。那么,我们开始吧:
public class WSDLFilterBehavior : IWsdlExportExtension, IEndpointBehavior
{
public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
{
// never called
}
public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
{
var schemas = exporter.GeneratedXmlSchemas.Schemas(@"http://Abc/Services/Data");
foreach (XmlSchema schema in schemas)
{
for (int i = schema.Items.Count - 1; i >= 0; --i)
{
// Do some other processing ...
var schemaComplexType = schema.Items[i] as XmlSchemaComplexType;
if (schemaComplexType == null)
{
continue;
}
XmlSchemaSequence xmlSchemaSequence;
var xmlSchemaContentModel = schemaComplexType.ContentModel;
if (xmlSchemaContentModel == null)
{
if (schemaType.Name.StartsWith("ArrayOf"))
{
continue;
}
xmlSchemaSequence = schemaComplexType.Particle as XmlSchemaSequence;
}
else
{
var xmlSchemaComplexContentExtension = xmlSchemaContentModel.Content as XmlSchemaComplexContentExtension;
if (xmlSchemaComplexContentExtension == null)
{
continue;
}
xmlSchemaSequence = xmlSchemaComplexContentExtension.Particle as XmlSchemaSequence;
}
if (xmlSchemaSequence == null)
{
continue;
}
var xmlSchemaObject = new XmlSchemaAny
{
MinOccurs = 0
};
xmlSchemaSequence.Items.Add(xmlSchemaObject);
}
}
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
// not needed
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
// not needed
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint,EndpointDispatcher dispatcher)
{
// not needed
}
public void Validate(ServiceEndpoint endpoint)
{
// not needed
}
}
它可以工作,它在所有元素中注入
xs:any
(不是xsd:any
,但我认为它是相同的),除了那些不是从任何其他类型派生并以“ArrayOf”开头的元素。你是说WSDL和xsd是由WCF生成的吗?换句话说,您的契约是代码优先,因此您正在寻找一种机制来更改生成的XSD?是的,的确如此。显然,我的契约不包含任何属性,但我确实希望将其注入WCF基础设施从代码中为我生成的WSDL中。