Пространства имен KSOAP и XML-форматирование запроса - PullRequest
1 голос
/ 19 декабря 2011

Я создаю приложение для Android, которое должно получать некоторые данные через интерфейс SOAP. Я пытаюсь использовать модуль KSOAP2 (используя ksoap2-android-2.6.0-jar-with-dependencies.jar). У меня проблемы с получением KSOAP, чтобы дать мне правильные префиксы пространства имен в дочерних элементах.

Я хочу это:

<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:GetRequest id="o0" c:root="1" xmlns:n0="http://dummy.com/nbi">
    <n0:Port i:type="d:string">Data</n0:Port>
</n0:GetRequest>
</v:Body></v:Envelope>

но ksoap2 дает мне это:

<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:GetRequest id="o0" c:root="1" xmlns:n0="http://dummy.com/nbi">
    <Port i:type="d:string">Data</Port>
</n0:GetRequest>
</v:Body></v:Envelope>

Единственное отличие состоит в том, что элемент Port во втором запросе XML не имеет префикса n0 на метке тега.

Я изучил правильную теорию XML пространства имен, и мне кажется, что правильно сформированный XML должен иметь префикс пространства имен для всех соответствующих элементов или родительский элемент должен иметь определение пространства имен по умолчанию. Играя с SoapUI, я могу вручную отправлять запросы на мой сервер и заставить работать любой из этих параметров, но я не могу понять, как заставить ksoap генерировать любой формат запроса. Т.е. я не могу понять, как создать элемент с пространством имен по умолчанию или как создать элемент с префиксом пространства имен для каждого дочернего элемента. Я испробовал все варианты настроек, о которых могу только подумать, но единственное (не элегантное) решение, которое я могу придумать, это вручную добавить префикс к метке порта. Кто-нибудь работал, как добиться того, чего я хочу? Моему SOAP-серверу не нравится запрос без строгого синтаксиса форматирования XML.

Вот соответствующий фрагмент кода:

private static final String namespace = "http://dummy.com/nbi";
private static final String URL = "http://192.168.254.117/soap/nbi";
String SOAP_ACTION = namespace + "/" + methodCall;
SoapObject request = new SoapObject(namespace, methodCall);
    PropertyInfo pi = new PropertyInfo();
pi.setName("myName");
pi.setValue("myString");
pi.setType(String.class);
    request.addProperty(pi);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = false;
envelope.setAddAdornments(false);       
envelope.implicitTypes = false;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;

try
   {
    List<HeaderProperty> headerList = new ArrayList<HeaderProperty>();
    headerList.add(new HeaderProperty("Authorization", "Basic " + org.kobjects.base64.Base64.encode("nbsam:nbsam".getBytes())));
        androidHttpTransport.call(SOAP_ACTION, envelope, headerList);
        SoapObject response = (SoapObject)envelope.getResponse();
        String result = response.getProperty(0).toString();

    }

Ответы [ 3 ]

2 голосов
/ 13 февраля 2014

Если вы хотите удалить пространство имен только из Property, вы можете установить пустую строку при создании PropertyInfo.Как это:

PropertyInfo pi = new PropertyInfo();
pi.setNamespace("");
pi.setName("myName");
pi.setValue("myString");
pi.setType(String.class);
2 голосов
/ 21 декабря 2011

Я решил это в то же время.Довольно просто, но я не видел других примеров этого при поиске.Просто нужно использовать метод setNamespace на PropertyInfo, который использовался для построения запроса.Как это:

pi.setNamespace("http://example.com/nbi");
0 голосов
/ 18 января 2012

Вы можете получить эффект пространства имен по умолчанию, используя следующую схему.

SoapObject request = new SoapObject(NAMESPACE, "GetRequest");
SoapObject data = new SoapObject("", "Port");
request.addSoapObject(data);

Это должно дать вам что-то вроде:

<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>
<GetRequest id="o0" c:root="1" xmlns:n0="http://dummy.com/nbi">
    <Port i:type="d:string">Data</Port>
</GetRequest>
</v:Body></v:Envelope>

Вы также можете сделать envelope.setAddAdornments(false) на конвертечтобы получить еще лучше:

<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>
<GetRequest xmlns:n0="http://dummy.com/nbi">
    <Port i:type="d:string">Data</Port>
</GetRequest>
</v:Body></v:Envelope>
...