我在这方面相当陌生.. 我有一个运行的 tomcat 服务器,我有一个 web 服务方法,当被调用时,返回一个字符串。当我尝试使用
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
// URL Request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:
[NSURL URLWithString:@"http://localhost:8080/WebServiceTutorialClient/sampleHelloProxy/Input.jsp?method=18"]];
[request setHTTPMethod:@"POST"];
// Send Request
[NSURLConnection sendAsynchronousRequest:request
queue:backgroundQueue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", result);
}];
我只是获取页面的内容,而不是该方法应该返回的字符串。这看起来很愚蠢,但我不知道如何获得该字符串。我确实成功地获得了响应(当我看到 NSLog 响应对象时),但我认为它只包含我返回的 html 数据。
我如何从我的 tomcat 服务器调用该方法,将字符串返回给我?非常感谢您的宝贵时间!
编辑:这是记录的响应:
<HTML>
<HEAD>
<TITLE>Inputs</TITLE>
</HEAD>
<BODY>
<H1>Inputs</H1>
<FORM METHOD="POST" ACTION="Result.jsp" TARGET="result">
<INPUT TYPE="HIDDEN" NAME="method" VALUE="18">
<BR>
<INPUT TYPE="SUBMIT" VALUE="Invoke">
<INPUT TYPE="RESET" VALUE="Clear">
</FORM>
</BODY>
</HTML>
编辑 2:这是 hello 服务图。我如何通过代码调用特定方法?
最佳答案
正如我们在聊天中讨论的那样,原始问题中的代码将用于测试 Web 服务的 HTML 用户界面与实际的 Web 服务本身混为一谈。您的示例代码正在对用于测试 Web 服务的 HTML 页面发出 HTTP 请求。您可能真的想直接与您的 Web 服务交互。
话虽如此,使用 SOAP/WSDL 网络服务接口(interface)会使过程变得相当复杂。在How to access SOAP services from iPhone讨论,我同意 schwa 的结论:“不要”。更重要的是,如果您正在编写一个新的 Web 服务,一些提供 JSON 的 REST 服务将更容易使用。或者,如果您坚持使用基于 SOAP 的服务,您可以编写一个新的 Web 服务来使用 SOAP 服务并提供 JSON。
如果您真的希望 iOS 应用程序直接与特定 WSDL 定义的 SOAP 服务交互,似乎有两种方法:首先,您可以使用其中一个源代码生成器(如 sudzc.com)。那里的这类解决方案让我不知所措。其次,您可以使用类似 Soap UI 的工具手动创建 XML
请求,然后将其用作 iOS 的模板。
所以,我尝试了后一种方法:
你提到你关注了the tutorial .我居然找到了this article在让 Web 服务运行方面更有用,但如果您在前者方面取得了成功,那很好。
我创建了一个网络服务,
HelloTest
, 与Hello
使用单一方法的类,sayHello
,它接受一个参数,name
,并返回"Hello " + name
:package com.tutorial; public class Hello { public String sayHello(String name){ return "Hello " + name; } }
我让 Eclipse 为我生成了 WSDL。细节无趣,但与您的并不完全不同:
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:ns="http://tutorial.com" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://tutorial.com"> <wsdl:documentation> Please Type your service description here </wsdl:documentation> <wsdl:types> <xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://tutorial.com"> <xs:element name="sayHello"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" name="name" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="sayHelloResponse"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> </wsdl:types> <wsdl:message name="sayHelloRequest"> <wsdl:part name="parameters" element="ns:sayHello"/> </wsdl:message> <wsdl:message name="sayHelloResponse"> <wsdl:part name="parameters" element="ns:sayHelloResponse"/> </wsdl:message> <wsdl:portType name="HelloPortType"> <wsdl:operation name="sayHello"> <wsdl:input message="ns:sayHelloRequest" wsaw:Action="urn:sayHello"/> <wsdl:output message="ns:sayHelloResponse" wsaw:Action="urn:sayHelloResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloSoap11Binding" type="ns:HelloPortType"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <wsdl:operation name="sayHello"> <soap:operation soapAction="urn:sayHello" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:binding name="HelloSoap12Binding" type="ns:HelloPortType"> <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <wsdl:operation name="sayHello"> <soap12:operation soapAction="urn:sayHello" style="document"/> <wsdl:input> <soap12:body use="literal"/> </wsdl:input> <wsdl:output> <soap12:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:binding name="HelloHttpBinding" type="ns:HelloPortType"> <http:binding verb="POST"/> <wsdl:operation name="sayHello"> <http:operation location="sayHello"/> <wsdl:input> <mime:content type="application/xml" part="parameters"/> </wsdl:input> <wsdl:output> <mime:content type="application/xml" part="parameters"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="Hello"> <wsdl:port name="HelloHttpSoap11Endpoint" binding="ns:HelloSoap11Binding"> <soap:address location="http://localhost:8080/HelloTest/services/Hello.HelloHttpSoap11Endpoint/"/> </wsdl:port> <wsdl:port name="HelloHttpSoap12Endpoint" binding="ns:HelloSoap12Binding"> <soap12:address location="http://localhost:8080/HelloTest/services/Hello.HelloHttpSoap12Endpoint/"/> </wsdl:port> <wsdl:port name="HelloHttpEndpoint" binding="ns:HelloHttpBinding"> <http:address location="http://localhost:8080/HelloTest/services/Hello.HelloHttpEndpoint/"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
我使用了 Soap UI获取 WSDL 并创建示例请求。
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tut="http://tutorial.com"> <soap:Header/> <soap:Body> <tut:sayHello> <!--Optional:--> <tut:name>Rob</tut:name> </tut:sayHello> </soap:Body> </soap:Envelope>
它可能对我的配置来说是独一无二的,但我不得不使用 Soap UI 生成的 SOAP 信封来替换 SOAP 1.2 URI:
http://www.w3.org/2003/05/soap-envelope
使用 SOAP 1.1 URI:
http://schemas.xmlsoap.org/soap/envelope/
为了举例,我还替换了
?
带有“Rob”的占位符(因为我希望我的 Web 服务向我问好)。无论如何,我现在可以通过以下 Objective-C 代码在 iOS 中提交该请求:
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/HelloTest/services/Hello"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; NSString *filename = [[NSBundle mainBundle] pathForResource:@"request1" ofType:@"xml"]; NSData *requestBodyData = [NSData dataWithContentsOfFile:filename]; request.HTTPBody = requestBodyData; [request setHTTPMethod:@"POST"]; [request addValue:@"http://tutorial.com" forHTTPHeaderField:@"SOAPAction"]; [request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { NSLog(@"%s", __FUNCTION__); if (data) { NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); } }];
显然,您如何创建
NSData
请求可能会有所不同(为了保持这种“简单”,我将 SOAP 请求的 XML 放入一个名为request1.xml
的文本文件中,并将其包含在我的包中)。同样,您发起请求的方式可能(我使用了NSURLConnection
方法,sendAsynchronousRequest
)。但希望这能让您了解如何发送手动创建的 SOAP 请求。生成的响应看起来像(我已经美化了它,但这是响应):
<?xml version='1.0' encoding='utf-8'?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <ns:sayHelloResponse xmlns:ns="http://tutorial.com"> <ns:return>Hello Rob</ns:return> </ns:sayHelloResponse> </soapenv:Body> </soapenv:Envelope>
然后您可以使用 XML 解析器解析此答案,例如
NSXMLParser
.
对我来说,“带回家”的信息是,除非万不得已,否则我不会这样做。我认为JSON
Web 服务同样易于创建,而且在 iOS 中使用它们的响应要容易得多。
关于ios - 尝试调用 Web 服务方法时从 NSURLResponse 返回的错误数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16376440/