- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在这方面相当陌生.. 我有一个运行的 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/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!