如何在使用KSoap2创造适当的SOAP信封(请求XML)在code? [英] How to create proper soap envelope (request xml) in code while using KSoap2?

查看:387
本文介绍了如何在使用KSoap2创造适当的SOAP信封(请求XML)在code?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是SOAP请求从SOAPUI通过喂食WSDL所获得的。

 < soapenv:信封的xmlns:soapenv =htt​​p://schemas.xmlsoap.org/soap/envelope/的xmlns:典型值=htt​​p://wsclient.xyz。 COM /类型/>
   < soapenv:页眉/>
   < soapenv:身体与GT;
      <典型值:loginserviceElement>
         <典型值:用户名> test.test< /类型:用户名>
         <典型值:密码> test123< /类型:密码>
      < /类型:loginserviceElement>
   < / soapenv:身体与GT;
< / soapenv:信封>
 

但Android的code倾倒(来自logcat中)的要求为:

 < XML版本=1.0编码=UTF-8&GT?;
<五:信封的xmlns:I =htt​​p://www.w3.org/2001/XMLSchema-instance的xmlns:D =htt​​p://www.w3.org/2001/XMLSchema
 的xmlns:C =htt​​p://schemas.xmlsoap.org/soap/encoding/的xmlns:V =htt​​p://schemas.xmlsoap.org/soap/envelope/>
    <五:页眉/>
    <五:身体与GT;
        < N0:login服务的xmlns:N0 =htt​​p://wsclient.xyz.com//>
            <用户名> test.test< /用户名>
            <密码> test1234< /密码>
        < / N0:login服务>
    < / V:车身>
< / V:信封>
 

我的问题是 - 既XML请求相同或应该可以互换?如果不是我怎么可以自定义的要求相匹配的一个我从SOAPUI得到什么?

正如在reposnce我得到:

的SOAPFault - 故障code:ENV:客户端在faultstring:处理请求,同时捕捉到异常:无法识别的操作:{的 http://wsclient.xyz.com// } login服务faultactor:'空'的细节:空

从SOAPUI(我试图在anddroid code才达到)响应:

 < ENV:身体与GT;
      < NS0:loginserviceResponseElement>
         < NS0:结果>
            < NS0:logintoken> 181210281021ahash< / NS0:logintoken>
            < NS0:hrmsid> 0000002< / NS0:hrmsid>
         < / NS0:结果>
      < / NS0:loginserviceResponseElement>
   < / ENV:身体与GT;
< / ENV:信封>
 

我已经尝试了许多答案,发现SO和其他教程用了成功。

我将不胜感激,如果引用很好的链接可以提供一些如何清楚地描述了不同的标签,如五:信封或soapenv:信封,N0:login服务或典型值:loginserviceElement或类型:loginserviceElement等

下面是Android code,以供参考:

 公开级SOA prequests {

    私有静态最终布尔DEBUG_SOAP_REQUEST_RESPONSE = TRUE;
    私有静态最后弦乐MAIN_REQUEST_URL =htt​​p://abc.xyz.com/WSClient/WSServiceSoapHttpPort;
    私有静态最后弦乐NAMESPACE =htt​​p://wsclient.xyz.com//;
    私有静态最后弦乐SOAP_ACTION =htt​​p://wsclient.xyz.com//loginservice;
    私有静态字符串SESSION_ID;

    私人最终无效testHtt presponse(HttpTransportSE HT){
        ht.debug = DEBUG_SOAP_REQUEST_RESPONSE;
        如果(DEBUG_SOAP_REQUEST_RESPONSE){
            Log.v(SOAP RETURN,请求XML:\ N+ ht.requestDump);
            Log.v(SOAP RETURN,\ñ\ñ\ nResponse XML:\ N+ ht.responseDump);
        }
    }

    公众用户getUserData(字符串名称,字符串PWD){
         用户USER = NULL;
         字符串方法名=login服务;

         SoapObject请求=新SoapObject空间(namespace,方法名);

         的PropertyInfo的userName =新的PropertyInfo();
         userName.setName(用户名);
         userName.setValue(名称);
         userName.setType(为String.class);
         request.addProperty(用户名);

         的PropertyInfo密码=新的PropertyInfo();
         password.setName(密码);
         password.setValue(PWD);
         password.setType(为String.class);
         request.addProperty(密码);

         SoapSerializationEnvelope信封= getSoapSerializationEnvelope(要求);
         HttpTransportSE HT = getHttpTransportSE();

         尝试 {
             ht.call(SOAP_ACTION,包);
             testHtt presponse(HT);
             SoapPrimitive resultsString =(SoapPrimitive)envelope.getResponse();
             字符串数据= resultsString.toString();
             Log.v(***********响应*******************,数据);

         }赶上(SocketTimeoutException如果T){
             t.printStackTrace();
         }赶上(IOException异常I){
             i.printStackTrace();
         }赶上(例外Q){
             q.printStackTrace();
         }

         //一些code设置用户数据
         ....
         返回用户;

    }

    私人SoapSerializationEnvelope getSoapSerializationEnvelope(SoapObject要求){
        SoapSerializationEnvelope包=新SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = FALSE;
        envelope.implicitTypes = TRUE;
        envelope.setAddAdornments(假);
        envelope.setOutputSoapObject(要求);
        回邮信封;
    }

    私人最终HttpTransportSE getHttpTransportSE(){
        HttpTransportSE HT =新HttpTransportSE(Proxy.NO_PROXY,MAIN_REQUEST_URL,60000);
        ht.debug = TRUE;
        ht.setXmlVersionTag(&所述;?xml的版本= \1.0 \编码= \UTF-8 \>?);
        返回羟色胺;
    }
}
 

编辑:从Android的code响应:

 < ENV:信封的xmlns:ENV =htt​​p://schemas.xmlsoap.org/soap/envelope/的xmlns:XSD =HTTP://www.w3。组织/ 2001 / XML模式的xmlns:XSI =http://www.w3.org/2001/XMLSchema-instance的xmlns:NS0 =http://wsclient.xyz.com/types/>
    < ENV:身体与GT;
    < ENV:故障>
        <故障code取代; ENV:客户< /故障code取代;
        &LT;在faultstring&GT;捕获异常处理请求的同时:无法识别的操作:{http://wsclient.hrms.com//}loginservice</faultstring>
    &LT; / ENV:故障&GT;
    &LT; / ENV:身体与GT;
&LT; / ENV:信封&GT;
 

解决方案

嗯我终于得到它后,一些调查研究工作,得到了问题的答案。

1)虽然SOAPUI genearted &LT; soapenv:信封的xmlns:soapenv =.........&GT; 键入响应XML和Android code。使用Ksoap2库genearted &LT;五:信封的xmlns:I =......&GT; 键入响应XML有不同的看标签,它不是在显著收到错误信息。两者是相似的。

正如前面提到的答案 SO质疑, KSOAP有硬codeD值中的SoapEnvelope的命名空间。

2)无法识别的操作异常是由于问题的MAIN_REQUEST_URL和命名空间。知道URL,命名空间和soap_action的正确的值是有点棘手,至少在这个领域的初学者。

这些字段的值可以通过查看请求/响应的xml,WSDL和这个漂亮图案的例子。

在我的情况,我不得不改变

  MAIN_REQUEST_URL =htt​​p://abc.xyz.com/WSClient/WSServiceSoapHttpPort;
NAMESPACE =htt​​p://wsclient.xyz.com//;
SOAP_ACTION =htt​​p://wsclient.xyz.com//loginservice;
 

  MAIN_REQUEST_URL =htt​​p://abc.xyz.com/WSClient/WSServiceSoapHttpPort?WSDL;
NAMESPACE =htt​​p://wsclient.xyz.com/types/;
SOAP_ACTION =htt​​p://wsclient.xyz.com//loginservice;
 

和我也不得不改变:

 字符串方法名=login服务;
 

 字符串方法名=loginserviceElement;
 

作为请求/响应XML有这个(典型值:loginserviceElement)标签包装的性能/参数

This is the soap request as obtained from SoapUi by feeding the wsdl.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://wsclient.xyz.com/types/">
   <soapenv:Header/>
   <soapenv:Body>
      <typ:loginserviceElement>
         <typ:username>test.test</typ:username>
         <typ:password>test123</typ:password>
      </typ:loginserviceElement>
   </soapenv:Body>
</soapenv:Envelope>

But the android code dumped (from logcat) the request as:

<?xml version="1.0" encoding= "UTF-8" ?>
<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema"
 xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
    <v:Header />
    <v:Body>
        <n0:loginservice xmlns:n0="http://wsclient.xyz.com//">
            <username>test.test</username>
            <password>test1234</password>
        </n0:loginservice>
    </v:Body>
</v:Envelope>

My question is- Is both the xml request are same or should work interchangeably? If not how can I customize the request to match the one I get from SoapUi?

As mentioned in the reposnce I am getting:

SoapFault - faultcode: 'env:Client' faultstring: 'Caught exception while handling request: unrecognized operation: {http://wsclient.xyz.com//}loginservice' faultactor: 'null' detail: null

Response from SoapUi (what I am trying to achive in anddroid code):

  <env:Body>
      <ns0:loginserviceResponseElement>
         <ns0:result>
            <ns0:logintoken>181210281021ahash</ns0:logintoken>
            <ns0:hrmsid>0000002</ns0:hrmsid>
         </ns0:result>
      </ns0:loginserviceResponseElement>
   </env:Body>
</env:Envelope>

I have tried many answer as found on SO and other tutorials with out success.

I would be grateful if a reference to good link can be provided that some how clearly describes the different tags like v:Envelope or soapenv:Envelope, n0:loginservice or typ:loginserviceElement or type:loginserviceElement etc

Below is the android code for reference:

public class SoapRequests {

    private static final boolean DEBUG_SOAP_REQUEST_RESPONSE = true;    
    private static final String MAIN_REQUEST_URL = "http://abc.xyz.com/WSClient/WSServiceSoapHttpPort";
    private static final String NAMESPACE = "http://wsclient.xyz.com//";
    private static final String SOAP_ACTION = "http://wsclient.xyz.com//loginservice";
    private static String SESSION_ID;

    private final void testHttpResponse(HttpTransportSE ht) {
        ht.debug = DEBUG_SOAP_REQUEST_RESPONSE;
        if (DEBUG_SOAP_REQUEST_RESPONSE) {
            Log.v("SOAP RETURN", "Request XML:\n" + ht.requestDump);
            Log.v("SOAP RETURN", "\n\n\nResponse XML:\n" + ht.responseDump);
        }
    }

    public User getUserData(String name, String pwd){       
         User user = null;
         String methodname = "loginservice";

         SoapObject request = new SoapObject(NAMESPACE, methodname);         

         PropertyInfo userName =new PropertyInfo();
         userName.setName("username");
         userName.setValue(name);
         userName.setType(String.class);
         request.addProperty(userName);

         PropertyInfo password =new PropertyInfo();
         password.setName("password");
         password.setValue(pwd);
         password.setType(String.class);
         request.addProperty(password);

         SoapSerializationEnvelope envelope = getSoapSerializationEnvelope(request);
         HttpTransportSE ht = getHttpTransportSE();

         try {
             ht.call(SOAP_ACTION, envelope);
             testHttpResponse(ht);
             SoapPrimitive resultsString = (SoapPrimitive)envelope.getResponse();
             String data = resultsString.toString();
             Log.v("***********RESPONSE*******************", data);

         } catch (SocketTimeoutException t) {
             t.printStackTrace();
         } catch (IOException i) {
             i.printStackTrace();
         } catch (Exception q) {
             q.printStackTrace();
         }

         // some code to set user data
         ....
         return user;

    }

    private SoapSerializationEnvelope getSoapSerializationEnvelope(SoapObject request) {
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = false;
        envelope.implicitTypes = true;
        envelope.setAddAdornments(false);
        envelope.setOutputSoapObject(request);
        return envelope;
    }

    private final HttpTransportSE getHttpTransportSE() {
        HttpTransportSE ht = new HttpTransportSE(Proxy.NO_PROXY,MAIN_REQUEST_URL,60000);
        ht.debug = true;
        ht.setXmlVersionTag("<?xml version=\"1.0\" encoding= \"UTF-8\" ?>");
        return ht;
    }
}

EDIT: RESPONSE from android code:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://wsclient.xyz.com/types/">
    <env:Body>
    <env:Fault>
        <faultcode>env:Client</faultcode>
        <faultstring>Caught exception while handling request: unrecognized operation: {http://wsclient.hrms.com//}loginservice</faultstring>
    </env:Fault>
    </env:Body>
</env:Envelope>

解决方案

Well finally I got it working after some more research and got the answers to the questions.

1) Though SoapUi genearted <soapenv:Envelope xmlns:soapenv="...." ....> type response xml and android code using Ksoap2 library genearted <v:Envelope xmlns:i="..." ...> type response xml have different looking tags, it is not significant in getting errors. Both are similar.

As mentioned on the answer to SO question, ksoap has hardcoded values for the namespace in SoapEnvelope.

2) The unrecognized operation exception was due to issue in the MAIN_REQUEST_URL and NAMESPACE. Knowing the proper value of url, namespace and the soap_action is bit tricky, at least for a beginner in this space.

The values of these fields can be set by looking at the request/response xml, wsdl and this nice pictorial example.

In my case, I had to change

MAIN_REQUEST_URL = "http://abc.xyz.com/WSClient/WSServiceSoapHttpPort";
NAMESPACE = "http://wsclient.xyz.com//";
SOAP_ACTION = "http://wsclient.xyz.com//loginservice";

to

MAIN_REQUEST_URL = "http://abc.xyz.com/WSClient/WSServiceSoapHttpPort?WSDL";
NAMESPACE = "http://wsclient.xyz.com/types/";
SOAP_ACTION = "http://wsclient.xyz.com//loginservice";

and also I had to change:

String methodname = "loginservice";

to

String methodname = "loginserviceElement";

as the request/response xml has this ( typ:loginserviceElement ) tag wrapping the properties/parameters.

这篇关于如何在使用KSoap2创造适当的SOAP信封(请求XML)在code?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆