【问题标题】:Create SOAP request using KSOAP Android使用 KSOAP Android 创建 SOAP 请求
【发布时间】:2012-02-22 14:34:50
【问题描述】:

我需要生成一个像这样的soap请求。

SOAP 请求

POST /TennisMasters/TennisMasters.Listener.asmx HTTP/1.1
Host: playinkstudio.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://playinktennismasters.com/authenticateUser"

    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <authenticateUser xmlns="http://playinktennismasters.com/">
          <user>string</user>
        </authenticateUser>
      </soap:Body>
    </soap:Envelope>

我正在使用 KSOAP2 来构建这个请求。

private static String SOAP_ACTION = "http://playinktennismasters.com/authenticateUser";
private static String NAMESPACE = "http://playinktennismasters.com/";
private static String METHOD_NAME = "authenticateUser";
private static String URL = "http://playinkstudio.com/TennisMasters/TennisMasters.Listener.asmx";

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    request.addProperty("user", "A Json String will be here");

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
            SoapEnvelope.VER12);
    envelope.dotNet = true;
    envelope.setOutputSoapObject(request);
    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
    androidHttpTransport.debug = true;
    try {
        androidHttpTransport.call(SOAP_ACTION, envelope);
    } catch (Exception e) {
        e.printStackTrace();
    }

这是我调试得到的请求。

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://www.w3.org/2003/05/soap-encoding" xmlns:v="http://www.w3.org/2003/05/soap-envelope">
<v:Header />
<v:Body>
<authenticateUser xmlns="http://playinktennismasters.com/" **id="o0" c:root="1"**>
<user **i:type="d:string"**>{"email":"asad.mahmood@gmail.com","UserDate":"Feb 22, 2012 7:01:24 PM","GearId":0,"GearValue":0,"Income":0,"Level":0,"MatchResult":0,"MatchType":0,"OfferId":0,"OpponentId":0,"Partners":0,"ExhibitionCount":0,"PowerRuns":0,"PowerServes":0,"PowerShots":0,"Seeds":0,"Energy":0,"Cash":0,"Stamina":0,"Strength":0,"SubLevel":0,"TotalEnergy":0,"TotalStamina":0,"TrainingId":0,"Agility":0,"UserId":0,"Age":0,"ActivityId":0,"gearIsGift":0}</user>
</authenticateUser>
</v:Body>
</v:Envelope>

我不知道为什么要在authenticateUser 中添加“id”和“c:root”等额外属性。 和 i:type="d:String" 中的额外属性。 请有人给我一个很好的例子或教程,可以指导我创建一个像上面这样的请求,真的需要帮助谢谢。

【问题讨论】:

  • 我假设您显示的第一个请求是从soapUI 获得的?您必须知道 ksoap2 的信封看起来与发送的 soap 有点不同,例如来自使用常规 soap 在 netbeans 中完成的 java 程序。这不是问题,两者都会得到相同的结果,只是xml。您是否从请求中收到错误,或者您只是担心额外添加的属性?
  • 嗨,请在这个聊天室联系我。我有一些疑问,这就是为什么,chat.stackoverflow.com/rooms/146715/soap

标签: android soap ksoap2


【解决方案1】:

我使用了简单的 HttpClient 和 Httppost, 请求信封的简单字符串。

        String temp = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
            + "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
            + "<soap:Body>"
            + "<authenticateUser xmlns=\"http://playinktennismasters.com/\">"
            + "<user>%s</user>" + "</authenticateUser>" + "</soap:Body>"
            + "</soap:Envelope>";
    ENVELOPE = String.format(temp, user);

现在使用的方法将创建发布请求的剩余参数并返回响应字符串。

public String CallWebService(String url, String soapAction, String envelope) {
    final DefaultHttpClient httpClient = new DefaultHttpClient();
    // request parameters
    HttpParams params = httpClient.getParams();
    HttpConnectionParams.setConnectionTimeout(params, 10000);
    HttpConnectionParams.setSoTimeout(params, 15000);
    // set parameter
    HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), true);

    // POST the envelope
    HttpPost httppost = new HttpPost(url);
    // add headers
    httppost.setHeader("soapaction", soapAction);
    httppost.setHeader("Content-Type", "text/xml; charset=utf-8");

    String responseString = "Nothingggg";
    try {

        // the entity holds the request
        HttpEntity entity = new StringEntity(envelope);
        httppost.setEntity(entity);

        // Response handler
        ResponseHandler<String> rh = new ResponseHandler<String>() {
            // invoked when client receives response
            public String handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {

                // get response entity
                HttpEntity entity = response.getEntity();

                // read the response as byte array
                StringBuffer out = new StringBuffer();
                byte[] b = EntityUtils.toByteArray(entity);

                // write the response byte array to a string buffer
                out.append(new String(b, 0, b.length));
                return out.toString();
            }
        };

         responseString = httpClient.execute(httppost, rh);

    } catch (Exception e) {
        e.printStackTrace();
        Log.d("me","Exc : "+ e.toString());

    }

    // close the connection
    httpClient.getConnectionManager().shutdown();
    return responseString;
}

【讨论】:

    【解决方案2】:

    要删除 id e c:root 属性,请将装饰设置为 false:

    envelope.setAddAdornments(false);
    

    要移除 i:type 属性,对于 SimpleTypes,将隐式类型设置为 true

    envelope.implicitTypes = true;
    

    但是在使用 ComplexTypes 时,要删除“i:type”,您需要 ksoap 3.0.0 RC1 或更高版本。我现在使用的是 3.0.0 RC2,但当它可用时,我会升级到稳定的 3.0.0 发布版本。

    【讨论】:

    • 三年后,你拯救了我的一天!非常感谢!
    【解决方案3】:

    终于让它与 KSOAP 一起工作了。这是我使用的代码,也许它会对某人有所帮助。

    final SoapObject request = new SoapObject(AppConsts.NAMESPACE,
                    usecaseString);
            request.addProperty(addPropertyString, propertyJsonString);
            final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                    SoapEnvelope.VER11);
            envelope.dotNet = true;
            envelope.setOutputSoapObject(request);
            final HttpTransportSE androidHttpTransport = new HttpTransportSE(
                    AppConsts.URL);
            androidHttpTransport.debug = true;
            String soapAction = AppConsts.NAMESPACE + usecaseString;
    
            try {
                androidHttpTransport.call(soapAction, envelope);
                SoapPrimitive resultSoapPrimitive;
                resultSoapPrimitive = (SoapPrimitive) envelope.getResponse();
                if (resultSoapPrimitive != null) {
                    result = resultSoapPrimitive.toString();
                    if (AppConsts.ENABLE_LOG)
                        Log.d(AppConsts.GAME_TITLE, "result json : " + result);
                } else {
                    if (AppConsts.ENABLE_LOG)
                        Log.d(AppConsts.GAME_TITLE, "result json is NULL!!! ");
    
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.e("static", "Exception in making call to server");
            }
    

    为了创建上述请求,我们需要将这三个参数传递给代码。

     AppConsts.NAMESPACE =  "http://playinktennismasters.com"
    usecaseString = "authenticateUser"
    addPropertyString = "user"
    

    【讨论】:

    • wt 是你的网址吗? .svc 还是 .asmx?
    • 我得到一个 a:InternalServiceFault
    • &lt;v:Body&gt; 是如何变为&lt;soap:Body&gt; 的?你做了什么改变?
    • 我不记得确切的行但你可以浏览工作代码,它对我来说很好。并仔细检查您的命名空间和 usecaseString
    • @waqas716:你能告诉我如何处理或解析复杂的SoapObject吗??
    【解决方案4】:

    这个通用示例是一个工作示例。肥皂网络请求发送:90 并返回“九十”。

    功能接口:

    package com.mindef.idttpda.soap;
    
    // function interface for two parameters
    @FunctionalInterface
    public interface Function2<One, Two> {
        public void apply(One one, Two two);
    }
    

    soap 请求类(带有多个参数:-):

    package com.mindef.idttpda.soap;
    
    // dependencies
    import org.ksoap2.SoapEnvelope;
    import org.ksoap2.serialization.PropertyInfo;
    import org.ksoap2.serialization.SoapObject;
    import org.ksoap2.serialization.SoapPrimitive;
    import org.ksoap2.serialization.SoapSerializationEnvelope;
    import org.ksoap2.transport.HttpTransportSE;
    import java.util.Map;
    
    /**
     * class for executing soap web service call.
     */
    public class SoapRequest implements Runnable {
    
        // soap response comes in here
        SoapResponse soapResponse;
    
        // webservice variables
        String url, namespace, method, action;
    
        // list of parameters for web service method
        Map<String, Object> parameters;
    
        /**
         * soap call to webservice
         * @param parameters - list with parameters for method of web service call.
         * @param soapResponse - response of web service call is put in here
         */
        public SoapRequest(Map<String, Object> parameters, SoapResponse soapResponse) {
            this.parameters = parameters;
            this.soapResponse = soapResponse;
        }
    
        /**
         * set url of web service
         * example: https://www.dataaccess.com/webservicesserver/NumberConversion.wso
         * @param url - url of web service
         * @return this - for method chaining
         */
        public SoapRequest url(String url) {
    
            this.url = url;
            return this;
        }
    
        /**
         * set namespace of web service
         * example: http://www.dataaccess.com/webservicesserver/
         * @param namespace - namespace of webservice
         * @return this - for method chaining
         */
        public SoapRequest namespace(String namespace){
            this.namespace = namespace;
            return this;
        }
    
        /**
         * set method of web service
         * example: NumberToWords
         * @param method - method to call on web service
         * @return this - for method chaining
         */
        public SoapRequest method(String method){
            this.method = method;
            return this;
        }
    
        /**
         * set soap action of web service call
         * example: https://www.dataaccess.com/webservicesserver/NumberConversion.wso/NumberToWords
         * @param action - full name of action to call on webservice
         * @return this - for method chaining
         */
        public SoapRequest action(String action){
            this.action = action;
            return this;
        }
    
        /**
         * execute soap web service call
         */
        @Override
        public void run() {
    
            // soap object.
            SoapObject soapObject = new SoapObject(this.namespace, this.method);
    
            // create parameters
            for(Map.Entry<String, Object> parameter : parameters.entrySet()) {
                PropertyInfo propertyInfo = new PropertyInfo();
                propertyInfo.setName(parameter.getKey());
                propertyInfo.setValue(parameter.getValue());
                propertyInfo.setType(String.class);
                soapObject.addProperty(propertyInfo);
            }
    
            // make soap envelope
            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            envelope.setOutputSoapObject(soapObject);
    
            // execute web request
            HttpTransportSE httpTransportSE = new HttpTransportSE(url);
            try {
                httpTransportSE.call(action, envelope);
                SoapPrimitive soapPrimitive = (SoapPrimitive) envelope.getResponse();
                soapResponse.complete(soapPrimitive.toString());
            }
    
            // exception handling
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * call soap web service
         */
        public void call() {
            new Thread(this).start();
        }
    };
    

    肥皂反应:

    package com.mindef.idttpda.soap;
    
    // dependencies
    import android.view.View;
    
    /**
     * class for executing function with response.
     */
    public class SoapResponse {
    
        // operation executed when response is received from web service
        Function2<View, String> completeFunction;
    
        // view where operation is executed on.
        View view;
    
        /**
         * soap response from soap web request.
         * @param view - view where function is executed on
         * @param completeFunction - function to execute when response is received
         */
        public SoapResponse(View view, Function2<View, String> completeFunction) {
            this.view = view;
            this.completeFunction = completeFunction;
        }
    
        /**
         * execute function with response
         * @param response - response from soap web request
         */
        public void complete(String response) {
            completeFunction.apply(view, response);
        }
    }
    

    如何调用soap web服务方法:

        /**
         * load userlist from database and put in spinner
         */
        private void loadWhatever(View loginView) {
    
            // execute soap web request.
            Map<String, Object> parameters = new HashMap<String, Object>();
            parameters.put("ubiNum","90");
            SoapResponse soapResponse = new SoapResponse(loginView, (view, string) -> this.loginOperation(view, string));
            new SoapRequest(parameters, soapResponse)
                .url("https://www.dataaccess.com/webservicesserver/NumberConversion.wso")
                .namespace("http://www.dataaccess.com/webservicesserver/")
                .action("https://www.dataaccess.com/webservicesserver/NumberConversion.wso/NumberToWords")
                .method("NumberToWords")
                .call();
    

    用您自己的函数替换 lambda 表达式。 lambda 函数在那里,所以它可以替换为您想要使用soap Web 服务响应的任何函数。您必须保留 lambda 签名。

    (view, string) -> this.loginOperation(view, string)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      • 2014-07-24
      • 1970-01-01
      • 2014-05-22
      • 1970-01-01
      相关资源
      最近更新 更多