Spring Boot如何控制自动生成WSDL的端口、服务及绑定名称?
解决方案:精细控制Spring Boot自动生成的WSDL名称
你的方向存在偏差:直接声明Soap11Provider Bean无法控制WSDL生成的服务名、绑定名等核心元素——Soap11Provider的作用是处理SOAP消息的传输协议、动作映射,而非WSDL的元数据生成。以下是正确的实现方案:
1. 利用DefaultWsdl11Definition配置所有WSDL名称元素
DefaultWsdl11Definition其实支持配置Port Type、服务名、绑定名等所有关键名称,你之前可能未完全利用其API。示例代码如下:
@Bean public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema contractSchema) { DefaultWsdl11Definition wsdlDefinition = new DefaultWsdl11Definition(); // 设置合同约定的目标命名空间 wsdlDefinition.setTargetNamespace("http://your-cobol-contract-namespace.com"); // 配置Port Type名称(对应WSDL中的<wsdl:portType>) wsdlDefinition.setPortTypeName("YourContractPortType"); // 配置绑定名称(对应WSDL中的<wsdl:binding>) wsdlDefinition.setBindingName("YourContractSoapBinding"); // 配置服务名称(对应WSDL中的<wsdl:service>,需指定完整QName匹配合同) wsdlDefinition.setServiceName(new QName("http://your-cobol-contract-namespace.com", "YourContractService")); // 设置SOAP 1.1的HTTP传输URI(匹配COBOL客户端的传输约定) wsdlDefinition.setTransportUri("http://schemas.xmlsoap.org/soap/http"); // 关联你的合同XSD Schema文件 wsdlDefinition.setSchema(contractSchema); return wsdlDefinition; } @Bean public XsdSchema contractSchema() { // 加载项目中与COBOL客户端约定的XSD文件 return new SimpleXsdSchema(new ClassPathResource("cobol-contract-schema.xsd")); }
2. 自定义Wsdl11Definition实现极致控制
如果DefaultWsdl11Definition的基础配置仍无法满足需求,可以扩展它并重写getDefinition()方法,直接修改生成的WSDL元数据:
public class CustomContractWsdlDefinition extends DefaultWsdl11Definition { @Override public Definition getDefinition() { Definition wsdlDefinition = super.getDefinition(); // 修改服务名称(覆盖自动生成的值) QName targetServiceQName = new QName("http://your-cobol-contract-namespace.com", "FixedServiceName"); Service existingService = wsdlDefinition.getService("DefaultService"); if (existingService != null) { wsdlDefinition.removeService(existingService.getQName().getLocalPart()); existingService.setQName(targetServiceQName); wsdlDefinition.addService(existingService); } // 修改绑定名称 QName targetBindingQName = new QName("http://your-cobol-contract-namespace.com", "FixedBindingName"); Binding existingBinding = wsdlDefinition.getBinding("DefaultBinding"); if (existingBinding != null) { wsdlDefinition.removeBinding(existingBinding.getQName().getLocalPart()); existingBinding.setQName(targetBindingQName); wsdlDefinition.addBinding(existingBinding); } // 可进一步修改端口名称、操作名称等其他WSDL元素 return wsdlDefinition; } }
然后将自定义类注册为Bean:
@Bean public Wsdl11Definition customWsdlDefinition(XsdSchema contractSchema) { CustomContractWsdlDefinition wsdlDefinition = new CustomContractWsdlDefinition(); wsdlDefinition.setTargetNamespace("http://your-cobol-contract-namespace.com"); wsdlDefinition.setPortTypeName("FixedPortTypeName"); wsdlDefinition.setSchema(contractSchema); return wsdlDefinition; }
3. Soap11Provider的正确用法(针对SOAP动作控制)
如果需要控制SOAP动作与Endpoint方法的映射,需将Soap11Provider与端点映射器结合使用,示例如下:
@Bean public SoapActionAnnotationMethodEndpointMapping soapActionEndpointMapping() { SoapActionAnnotationMethodEndpointMapping mapping = new SoapActionAnnotationMethodEndpointMapping(); mapping.setMessageFactory(saajSoapMessageFactory()); return mapping; } @Bean public SaajSoapMessageFactory saajSoapMessageFactory() { return new SaajSoapMessageFactory(); } @Bean public Soap11Provider soap11Provider() { Soap11Provider provider = new Soap11Provider(); provider.setMessageFactory(saajSoapMessageFactory()); // 若需自定义传输URI可在此设置 provider.setTransportUri("http://schemas.xmlsoap.org/soap/http"); return provider; }
然后在Endpoint方法上通过@SoapAction指定合同约定的动作:
@Endpoint public class CobolContractEndpoint { @PayloadRoot(namespace = "http://your-cobol-contract-namespace.com", localPart = "ContractRequest") @SoapAction("http://your-cobol-contract-namespace.com/FixedSoapAction") @ResponsePayload public ContractResponse handleContractRequest(@RequestPayload ContractRequest request) { // 业务逻辑处理 } }
内容的提问来源于stack exchange,提问作者Eric JB.
相关产品推荐
相关产品推荐

