2013-05-04 113 views
1

即時消息相當新在此..我有一個Tomcat服務器運行,並且我有一個Web服務方法那裏,當調用時返回一個字符串。當我嘗試使用嘗試調用Web服務方法時從NSURLResponse返回的錯誤數據

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); 
         }]; 

我剛剛得到的頁面內容,而不是本來該方法返回的字符串。這prolly看起來很傻,但我不知道如何得到該字符串。我確實得到了響應成功(當我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 service

+0

Rob - 現在編輯主文章和記錄結果。謝謝你的評論! – Zephyer 2013-05-04 16:42:17

+0

Rob - 當我到代碼的地址時,我會看到html所說的內容 - 我看到一個帶有「invoke」和「clear」的按鈕,並帶有標題。當我點擊'invoke'時,我打開另一個標籤,標題'result'和它應該返回的文本。這有助於確定我的問題是什麼? – Zephyer 2013-05-04 16:53:11

+0

Rob - 看起來你是對的,我在「http:// localhost:8080/WebServiceTutorial/services/Hello」找到了我的hello服務的地址。但是,我如何調用特定的方法?我將張貼描述我的意思的圖片 – Zephyer 2013-05-04 17:07:50

回答

0

正如我們在聊天中討論的,原始問題中的代碼將用於測試Web服務的HTML用戶界面與實際的Web服務本身混合在一起。您的示例代碼正在製作用於測試Web服務的HTML頁面的HTTP請求。你真的很想直接與你的網絡服務交互。

話雖如此,使用SOAP/WSDL Web服務接口使過程變得非常複雜。在討論How to access SOAP services from iPhone時,我會同意schwa的結論:「不要」。更重要的是,如果你正在編寫一個新的Web服務,那麼提供JSON的一些REST服務將會容易得多。或者,如果您堅持使用基於SOAP的服務,則可以編寫一個新的Web服務,該服務使用SOAP服務並提供JSON。

如果您確實希望iOS應用程序直接與由特定WSDL定義的SOAP服務交互,那麼似乎有兩種方法:首先,您可以使用其中一種源代碼生成器(如sudzc.com)。那裏的這種解決方案讓我感到不知所措。其次,您可以使用像Soap UI這樣的工具爲請求手動創建XML,然後將其用作iOS中的模板。

所以,我嘗試了後一種辦法:

  1. 你提到你遵循the tutorial。實際上,我發現this article在使Web服務正常運行時更有用,但如果您與前者取得了成功,那很好。

  2. 我創建了一個Web服務,HelloTest,具有Hello類一個方法,sayHello,這需要一個參數,即name,並返回"Hello " + name

    package com.tutorial; 
    
    public class Hello { 
        public String sayHello(String name){ 
         return "Hello " + name; 
        } 
    } 
    
  3. 我的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> 
    
  4. 我以前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> 
    

    這可能是唯一的我的配置,但我不得不玩的肥皂UI生成的SOAP信封,取代了SOAP 1.2 URI:用SOAP 1.1 URI

    http://www.w3.org/2003/05/soap-envelope 
    

    http://schemas.xmlsoap.org/soap/envelope/ 
    

    我還舉例的目的,取代了?佔位符「羅布」(因爲我想我的Web服務來跟我打招呼)。

  5. 反正我現在可以在iOS中通過以下Objective-C代碼提交請求:

    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請求。

  6. 這產生看起來像一個響應(我美化它,但是這是響應):

    <?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網絡服務同樣容易創建,並且在iOS中消費他們的響應要容易得多。

相關問題