Waqas
Waqas

Reputation: 4489

Create SOAP request using KSOAP Android

I need to generate a soap request like this one.

SOAP-REQUEST

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>

I am using KSOAP2, to build this request.

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

This is the request which I got from debugging.

<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":"[email protected]","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>

I don't know why extra attributes like "id" and "c:root" are being added in authenticateUser. and extra attribute in i:type="d:String". Please can come someone give me a good example or tutorial which can guide me to create a request like above,Really Need help thanks.

Upvotes: 4

Views: 10719

Answers (4)

Herman Van Der Blom
Herman Van Der Blom

Reputation: 812

This generic sample is a working example. The soap web request sends: 90 and gets back "ninety".

function interface:

package com.mindef.idttpda.soap;

// function interface for two parameters
@FunctionalInterface
public interface Function2<One, Two> {
    public void apply(One one, Two two);
}

soap request class (with multiple parameters :-):

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

soap response:

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

how to call soap web service method:

    /**
     * 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();

Replace the lambda expression with your own function. The lambda function is there so it can be replaced with whatever function you want to use the soap web service response for. You must keep the lambda signature.

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

Upvotes: 0

Alexandre
Alexandre

Reputation: 389

to remove id e c:root attributes set the adornments to false:

envelope.setAddAdornments(false);

to remove i:type attribute, for SimpleTypes, set the implicit types to true

envelope.implicitTypes = true;

but when working with ComplexTypes, to remove the "i:type" you´ll need the ksoap 3.0.0 RC1 or above. Im using 3.0.0 RC2 by now, but I´ll upgrade to stable 3.0.0 release version, when it becomes available.

Upvotes: 4

Waqas
Waqas

Reputation: 4489

Finally got it working with KSOAP. Here is the code I used maybe it will help someone.

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

For creating above request these three parameter we need to pass into code.

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

Upvotes: 1

Waqas
Waqas

Reputation: 4489

I used simple HttpClient and Httppost, Simple String for request Envelope.

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

Now using Method which will create post request remaining parameters and will return the response String.

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

Upvotes: 5

Related Questions