我正在使用一个 API,该 API 对于特定类型的函数有两个不同的 URL。第一个是支持 JSON 或 SOAP 请求的事务 API。我已经使用专门的 JSON 调用在这个 API 中调用了我需要的所有函数,并且一切似乎都运行良好。
第二个是用于查找和/或下载报告的报告 API。此 API 专门用于 SOAP。我无法让这个 API 中的任何功能正常工作。我试图联系公司的支持小组,但他们没有任何人可以帮助我在 ColdFusion 中调用 API。我尝试了两种不同的方式来与这个 API 交互并访问这些函数,但结果都是空的。以下是我的示例以及我可以提供的尽可能多的信息;我们的服务提供商的 API 和相关文档是保密的,但我可以回答一些与我的代码有关的具体问题。
方式1:创建一个webservice对象。
我尝试创建此 SOAP 调用的第一种方法是通过 web 服务对象。使用元数据交换点 URL,我将它传递给 createObject 函数,如下所示:
<cfset argStruct = structNew() />
<cfset argStruct['username'] = 'myusername' />
<cfset argStruct['password'] = 'mypassword' />
<cfset testSvc = createObject('webservice','https://brandnameapi.sandbox.serviceprovider.com/vernum/ReportingAPI.svc/mex',argStruct) />
当我运行此代码时,我收到以下错误消息:
无法为 Web 服务调用生成存根对象。名称:https ://brandnameapi.sandbox.serviceprovider.com/vernum/ReportingAPI.svc/mex 。WSDL:https ://brandnameapi.sandbox.serviceprovider.com/vernum/ReportingAPI.svc/mex 。javax.wsdl.WSDLException: WSDLException (at /wsdl:definitions/wsdl:import): faultCode=OTHER_ERROR: Unable to resolve import document at 'https://brandnameapi.sandbox.serviceprovider.com/vernum/ReportingAPI.svc/mex? wsdl=wsdl1',相对于 'brandnameapi.sandbox.serviceprovider.com/vernum/ReportingAPI.svc/':java.io.IOException:服务器返回 HTTP 响应代码:401 对于 URL:https://brandnameapi.sandbox.serviceprovider。 com/vernum/ReportingAPI.svc/mex?wsdl=wsdl1
由于 401 错误通常是错误的授权,因此我通过直接在浏览器中调用 URL 来仔细检查地址,并在浏览器中提示我使用 UN/PW。我输入了我的值,并被允许访问 URL,并收到此 XML 作为回报:
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions name="ReportingAPI" targetNamespace="https://https://brandnameapi.serviceprovider.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:tns="https://https://brandnameapi.serviceprovider.com" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:i0="https://https://brandnameapi.serviceprovider.com/ReportingAPI/soapBinding" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<wsdl:import namespace="https://https://brandnameapi.serviceprovider.com/ReportingAPI/soapBinding" location="https://https://brandnameapi.sandbox.serviceprovider.com/vernum/ReportingAPI.svc/mex?wsdl=wsdl1"/>
<wsdl:types/>
<wsdl:service name="ReportingAPI">
<wsdl:port name="BasicHttpBinding_IReportingAPI" binding="i0:BasicHttpBinding_IReportingAPI">
<soap:address location="https://https://brandnameapi.sandbox.serviceprovider.com/vernum/ReportingAPI.svc/soap"/>
</wsdl:port>
</wsdl:service>
这大约是我所得到的。当我用浏览器调用 URL 并传递身份验证信息时,我就可以访问 XML。当我尝试使用 ColdFusion 执行此操作时,我收到 401 错误。
方式2:cfhttp请求调用
当我切换到使用 cfhttp 时,我似乎走得更远了。当我使用这个时:
<cfhttp url="https://brandnameapi.sandbox.serviceprovider.com/vernum/ReportingAPI.svc/mex"
username="myusername" password="mypassword" method="get" result="httpResponse"
timeout="300">
</cfhttp>
httpResponse 返回适当的页面信息,并且 httpResponse.filecontent 返回我在浏览器中直接调用它时收到的相同 XML。
更进一步,我使用 SOAP URL 并尝试调用 API 中的函数,该函数返回可用报告文件的列表。我使用了与事务 API 中所有 JSON 调用相同的已知工作流程:
<cfhttp url="https://brandnameapi.sandbox.serviceprovider.com/vernum/ReportingAPI.svc/soap/queryAvailableReportFiles"
username="myusername" password="mypassword" method="post"
result="httpResponse" timeout="300">
<cfhttpparam type="formfield" name="typeOfReport" value="DailyCSVFile" />
</cfhttp>
当我运行此代码时,我收到状态代码 415 和错误“无法处理消息,因为内容类型 'application/x-www-form-urlencoded' 不是预期的类型 'multipart/related; 类型="应用程序/xop+xml"'
当我在我的 cfhttps 之间添加这一行时:
<cfhttpparam type="header" name="Content-Type" value='multipart/related; type="application/xop+xml"' />
我得到与上面相同的错误,但状态代码更改为 400。我没有包括我尝试做的所有事情,只包括我现在所在的位置。我将尽可能多地回答问题,并将按照指示重新执行步骤以找到解决此问题的方法。
更新:根据要求,我已更改 cfhttp 调用以尝试传递 XML 而不是表单字段。我的 XML 代码是直接从 API 文档中提取的,该文档有一个原始数据示例,用于从 API 请求不同功能的原始数据:
<cfsavecontent variable="soapBody">
<cfoutput>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<queryAvailableReportFiles
xmlns="https://brandnameapi.sandbox.serviceprovider.com/contract">
<fileName>DailyCSVFile</fileName>
</queryAvailableReportFiles>
</s:Body>
</s:Envelope>
</cfoutput>
</cfsavecontent>
<cfhttp url="https://prismproapi.sandbox.koretelematics.com/4/ReportingAPI.svc/soap/queryAvailableReportFiles" username="vfapi" password="bPzqQyK3" method="post" result="httpResponse" timeout="300">
<cfhttpparam type="xml" value="#trim(soapBody)#" />
</cfhttp>
公平地说,我不知道我是否做得对。从它返回的错误消息是,“由于 EndpointDispatcher 的 AddressFilter 不匹配,接收方无法处理带有 To https://prismproapi.sandbox.koretelematics.com/4/ReportingAPI.svc/soap/queryAvailableReportFiles的消息. 检查发送方和接收方的 EndpointAddresses 是否一致。” 我也收到 500 错误。