Получение настраиваемых объектов из веб-службы .NET на основе SOAP в Android

Я разрабатываю приложение для Android, которому необходимо подключиться к веб-службе .NET SOAP и создать / заполнить ряд объектов из ответа. Я новичок в веб-сервисах и SOAP и относительно новичок в Android. Веб-сервис уже создан (не мной).

Я пытался найти информацию о подключении к веб-службам SOAP в Android. Вот два основных предложения:

  1. Не используйте SOAP,
  2. Если вы все же используете SOAP, используйте KSOAP2.

Я просмотрел различные руководства для KSOAP2, но все они, похоже, имеют дело только с самыми простыми, примитивными типами, такими как отправка 2 int для возврата 1 int или отправка и получение строк; однако мне нужно отправлять настраиваемые объекты назад и вперед.

Можно ли отправлять и получать настраиваемые объекты с помощью KSOAP2? Если да, то насколько это легко / сложно? Нужно ли разбирать XML для создания / заполнения объектов «вручную»?

ИЗМЕНИТЬ / ОБНОВИТЬ: Попытавшись некоторое время подключиться к существующей веб-службе (принимает String и возвращает сложный объект) и получив сообщение об ошибке, я решил попробовать более простой подход. Я подключился к более простому веб-сервису, который не принимает параметров и возвращает int. Этот более простой веб-сервис размещен в том же месте, что и исходный, и теперь мне подходит более простой.

ДАЛЬНЕЙШЕЕ ОБНОВЛЕНИЕ: Теперь все работает нормально! Оказывается, у меня просто была ошибка с заглавными буквами, из-за которой мой параметр был сброшен.

Последняя проблема была «национальный» против «национального». Вот код, созданный с помощью soapUI:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:tem="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:GetClientByNationalID>
         <!--Optional:-->
         <tem:nationalID>XXXXXXX</tem:nationalID>
      </tem:GetClientByNationalID>
   </soapenv:Body>
</soapenv:Envelope>

И код запроса, созданный моей Java:

<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>
        <GetClientByNationalID xmlns="http://tempuri.org/" id="o0" c:root="1">
            <NationalID i:type="d:string">
                XXXXXXXX
            </NationalID>
        </GetClientByNationalID>
    </v:Body>
</v:Envelope>

Мой последний код Java:

public void webServiceCall() {
    String NAMESPACE = "http://tempuri.org/";
    String METHOD_NAME = "GetClientByNationalID";
    String SOAP_ACTION = "http://tempuri.org/IClientService/GetClientByNationalID"; 

    // unsecure service
    String URL = "http://XXXXXXXXXXXXXXXXXXXX.net/FPUnSecureService/ClientService.svc";

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 

    String clientID = "XXXXXXX";

    PropertyInfo pi = new PropertyInfo();
    pi.setName("nationalID"); 
    pi.setValue(clientID); 
    pi.setType(clientID.getClass()); 
    request.addProperty(pi);

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
    envelope.dotNet = true;
    envelope.setOutputSoapObject(request); 

    envelope.addMapping(NAMESPACE, "GetClientByNationalID", new ClientID().getClass());
    Marshal floatMarshal = new MarshalFloat();
    floatMarshal.register(envelope);

    HttpTransportSE t = new HttpTransportSE(URL); 

    ClientID client = new ClientID(); 
    t.debug = true; 

    try { 
        Log.i("webServiceCall", "Trying call to web service");
        t.call(SOAP_ACTION, envelope);
        SoapObject response = (SoapObject) envelope.getResponse();

        Log.i("success", response.getPropertyAsString(0)); 
        Log.i("success", response.getPropertyAsString(1));
        Log.i("success", response.getPropertyAsString(2));
        Log.i("success", response.getPropertyAsString(3));
        Log.i("success", response.getPropertyAsString(4)); 

    } catch (Exception e) {
        Log.e("webServiceCall", "Error calling webservice.");
        e.printStackTrace(); 
        System.out.println("Request: "  + t.requestDump); 
        System.out.println("Response: " + t.responseDump);
    }

}

Я до сих пор не понимаю эти строки:

envelope.addMapping(NAMESPACE, "GetClientByNationalID", new ClientID().
Marshal floatMarshal = new MarshalFloat();
floatMarshal.register(envelope);

Я думаю, что добавил части Marshal, когда передавал объект в качестве параметра, я не уверен, что они мне еще нужны. Я также не уверен в вызове addMapping и в том, что мне там нужно. Спасибо.


person breadbin    schedule 03.02.2012    source источник


Ответы (2)


Используйте ksoap2 и проверьте мои ответы с помощью примеров кода по следующим ссылкам: Link1, link2, link3. Я написал несколько деталей, которые помогут вам понять, как начать кодить.
дайте мне знать, если вам понадобится помощь.

ОБНОВЛЕНИЕ (отвечая на ваш вопрос о сопоставлении и сортировке)
вы используете addMapping, когда вы отправляете сложный тип (например, объект) через мыльный конверт. Как веб-сервис распознает сложный тип? Вам нужно создать локально класс, реализующий kvmserializable (как указано в моих ссылках), который будет иметь тот же параметр, что и объект на сервере, а затем вам нужно добавить сопоставление между ним и классом, который сопоставляет к нему на сервере, так что конверт при синтаксическом анализе на сервере знает, что этот сложный тип X отображается в класс X на сервере. Поэтому, если вы не отправляете сложный тип, вам не нужно добавлять сопоставление. (PS: Я вижу, что вы не отправляете сложный тип, так как nationalID имеет тип string. ЕСЛИ позволяет сказать, что nationalID был сложным типом типа Z, вы бы сделали: addMapping (NAMESPACE, Z.class.getSimpleName (), Z.class))

Что касается маршаллинга, он использует сериализацию Java для преобразования объектов в поток данных, которые будут немаршалированы в веб-службе. Поэтому, когда вы отправляете сложный тип, исходя из моего опыта, рекомендуется добавить маршаллинг для изменения сложного типа в потоках данных путем его сериализации. Если вы обнаружите, что он вам не нужен, просто не добавляйте его, но всегда полезно понять, какие есть варианты.

person ccot    schedule 04.02.2012
comment
Спасибо @Shadesco, они очень полезны. Я пытаюсь подключиться к веб-сервису сейчас и получаю ошибку org.xmlpull.v1.XmlPullParserException: неожиданный тип (позиция: END_DOCUMENT null @ 1: 0 в java.io.InputStreamReader@4052d908). Есть ли у вас какие-нибудь идеи по этому поводу? - person breadbin; 06.02.2012
comment
@breadbin это похоже на проблему с анализом ответа, но в любом случае мне нужно посмотреть код, чтобы помочь вам. повторно отредактируйте сообщение, добавьте немного своего кода и сообщите мне, где возникает ошибка - person ccot; 06.02.2012
comment
спасибо за ответ, я обновил вопрос, добавив более подробную информацию и код. - person breadbin; 07.02.2012
comment
@breadbin кажется, что проблема с вашей строкой SOAP_ACTION, вы уверены, что это правильный URL-адрес? или, может быть, сервер, как он говорит, требует дополнительной защиты? простой веб-сервис, к которому вы подключились, выполняет ли он то же действие, что и этот? - person ccot; 07.02.2012
comment
Я преодолел ошибку ActionNotSupported и теперь получаю ошибку параметра, что, на мой взгляд, является хорошим знаком! Я обновил код и сообщение об ошибке. - person breadbin; 07.02.2012
comment
@breadbin хорошо, я вижу, это сработало, хорошие вещи! по поводу addMapping, я обновляю свой ответ выше, проверьте его - person ccot; 07.02.2012

Взгляните на этот http://seesharpgears.blogspot.com/2010/10/ksoap-android-web-service-tutorial-with.html есть примеры того, как передавать сложные объекты.

person Marcos    schedule 03.02.2012