使用marshalSendAndReceive调用SOAP服务返回500错误求助
问题分析与修复方案
核心问题根源
- 完全错误理解了SOAP请求的传输逻辑:SOAP是基于XML的结构化请求,你却把参数URL编码成字符串当成payload传递,这和服务端期望的SOAP XML结构完全不匹配,是导致500错误的核心原因。
- URL拼接错误:ASMX的SOAP服务不需要在基础URL后追加
/calculate_MD5,基础URLhttp://********/ProCONWS/WebService_PCSOrderEntry.asmx就是服务入口,方法调用是通过SOAP请求体XML或SOAPAction HTTP头指定的。
修复后的代码示例
String PROCON_SOAP_ACCESS_URL = "http://********/ProCONWS/WebService_PCSOrderEntry.asmx"; public CalculateMD5Response calculateMD5(final String userName) { String msg = null; CalculateMD5Response response = null; try { // 构建符合WSDL定义的SOAP请求对象 ObjectFactory objectFactory = new ObjectFactory(); CalculateMD5 request = objectFactory.createCalculateMD5(); request.setUser("pcscord"); request.setTimestamp(DateUtil.dateToString(new Date(), "yyyyMMdd HHmmss")); request.setSecretWord("********"); logger.info("About to call Procon SOAP Service: " + PROCON_SOAP_ACCESS_URL + "."); // 直接传递请求对象,WebServiceTemplate会自动序列化为标准SOAP XML Object result = getWebServiceTemplate().marshalSendAndReceive( PROCON_SOAP_ACCESS_URL, request, webServiceMessage -> { // 设置SOAPAction头,值需从WSDL中获取(通常是命名空间+方法名,比如"http://tempuri.org/calculate_MD5") ((SoapMessage) webServiceMessage).setSoapAction("http://tempuri.org/calculate_MD5"); } ); // 转换为正确的响应对象类型 if (result instanceof JAXBElement) { response = ((JAXBElement<CalculateMD5Response>) result).getValue(); } else if (result instanceof CalculateMD5Response) { response = (CalculateMD5Response) result; } logger.info("Called Procon SOAP service. Response: " + response); } catch (Exception e) { msg = "FAILURE: There was an error calling the Procon SOAP service. Exception: "+e.getMessage()+". URL: "+PROCON_SOAP_ACCESS_URL+"."; logger.error(msg); } return response; }
额外注意事项
- SOAPAction头必须准确:从服务提供的WSDL里找到
calculate_MD5方法对应的SOAPAction值,一般在<operation>标签下的<soap:operation soapAction="..." />节点中,错误的SOAPAction会导致服务端无法识别调用方法。 - 禁止手动编码参数:WebServiceTemplate结合JAXB会自动完成XML序列化与编码,无需用
URLEncoder处理参数。 - 验证Stub正确性:确认生成的
CalculateMD5、CalculateMD5Response等类的字段名、类型和WSDL定义完全匹配(比如注意Secret_word和secretWord的大小写、命名风格差异)。 - 开启SOAP日志排查:通过配置日志查看实际发送的SOAP请求和服务端错误响应,快速定位问题:
logging.level.org.springframework.ws.client.MessageTracing.sent=TRACE logging.level.org.springframework.ws.client.MessageTracing.received=TRACE
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

