Spring调用SOAP接口请求方法为GET而非POST如何解决
问题根源
你当前请求方法异常为GET的核心原因有两个:
- 调用
marshalSendAndReceive方法时,第一个参数错误传入了WSDL文件地址,该参数应填写SOAP服务的业务接口端点地址。WSDL地址通常仅支持GET请求获取描述文件,业务接口才是接收POST请求的实际地址,框架会针对WSDL地址默认发送GET请求获取元数据,导致你业务请求方法异常。 - 没有显式指定HTTP请求方法,框架自动推断时出现偏差。
修复步骤
步骤1:修改业务调用的端点地址
将StoreInformationClient类中marshalSendAndReceive的第一个参数,替换为服务商提供的实际SOAP业务端点地址(通常是WSDL文档中<wsdl:port>标签下<soap:address location>属性对应的地址),不要传入WSDL文件地址。
修改后代码示例:
return (StoreInformation) getWebServiceTemplate() // 替换为实际业务端点,比如https://aurl.com/api/ws 这类地址,不要带.wsdl后缀 .marshalSendAndReceive("https://aurl.com/api/ws", SoapUtils.buildEnvelope(storeInformation, StoreInformation.class), new PartnerWSHttpHeaderCallBack());
步骤2:显式指定HTTP请求方法为POST
在PartnerWSHttpHeaderCallBack的addRequestHeader方法中,新增设置请求方法的逻辑,避免框架自动推断错误:
修改后代码示例:
private void addRequestHeader(Map<String, String> headers) { TransportContext context = TransportContextHolder.getTransportContext(); WebServiceConnection connection = context.getConnection(); if (connection instanceof HttpUrlConnection) { HttpUrlConnection conn = (HttpUrlConnection) connection; try { // 新增这一行,强制指定请求方法为POST conn.getConnection().setRequestMethod("POST"); } catch (IOException e) { e.printStackTrace(); } for (Map.Entry<String, String> entry : headers.entrySet()) { String k = entry.getKey(); String v = entry.getValue(); try { conn.addRequestHeader(k, v); } catch (IOException e) { e.printStackTrace(); } } } }
可选优化(避免后续地址配置错误)
可以在配置类初始化StoreInformationClient时,就统一设置默认端点地址,不用每次调用时单独传入:
修改AppConfiguration中的countryClient方法:
@Bean public StoreInformationClient countryClient(Jaxb2Marshaller marshaller) { StoreInformationClient client = new StoreInformationClient(); client.setMarshaller(marshaller); client.setUnmarshaller(marshaller); // 统一设置默认业务端点地址 client.setDefaultUri("https://aurl.com/api/ws"); return client; }
后续调用时直接使用无地址参数的marshalSendAndReceive重载方法即可:
return (StoreInformation) getWebServiceTemplate() .marshalSendAndReceive(SoapUtils.buildEnvelope(storeInformation, StoreInformation.class), new PartnerWSHttpHeaderCallBack());
内容的提问来源于stack exchange,提问作者Renato Souto
相关产品推荐
相关产品推荐

