У меня проблема при доступе к ресурсу WSDL с базовой аутентификацией из Android.
Код:
package ru.itgorod.test.wsdl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.ksoap2.HeaderProperty;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class WSDLTestActivity extends Activity {
private static final String NAMESPACE = "http://www.example.ru/lecompre";
private static final String URL="http://10.0.0.233/lecompre/ws/lecompre?wsdl";
private static final String METHOD_NAME = "GetGoodsList";
private static final String SOAP_ACTION = "http://www.example.ru/lecompre/GetGoodsList";
private static final String USERNAME = "WS";
private static final String PASSWORD = "";
private TextView txt;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt = (TextView) findViewById(R.id.textView1);
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
Log.i("wsdl", "1");
androidHttpTransport.debug = true;
StringBuffer auth = new StringBuffer(USERNAME);
auth.append(':').append(PASSWORD);
byte[] raw = auth.toString().getBytes();
auth.setLength(0);
auth.append("Basic ");
org.kobjects.base64.Base64.encode(raw, 0, raw.length, auth);
List<HeaderProperty> headers = new ArrayList<HeaderProperty>();
headers.add(new HeaderProperty("Authorization", auth.toString())); // "Basic V1M6"));
try {
Log.i("wsdl", "2");
Object response = androidHttpTransport.call(SOAP_ACTION, envelope, headers); // I got an XmlPullParserException here
Log.i("wsdl", "3");
} catch (IOException e) {
txt.setText("IOException");
} catch (XmlPullParserException e) {
txt.setText("XmlPullParserException");
}
SoapObject result = null;
try {
Log.i("wsdl", "4");
result = (SoapObject)envelope.getResponse();
Log.i("wsdl", result.toString());
} catch (SoapFault e) {
txt.setText("SoapFault");
}
}
}
На androidHTTPTransport.call () я получил исключение.Сервер возвращает ответ «Доступ запрещен».Но, как я вижу в отладке, заголовок «авторизации» androidHTTPTransport.connection.connection.reqHeader.props уже здесь: [user-agent, kSOAP / 2.0, тип контента, text / xml, соединение, закрытие, длина контента, 330, авторизация, Basic V1M6] Но в resHeader я получил «Требуется авторизация HTTP / 1.1 401».
Когда я пытаюсь открыть URL в браузере - он работает нормально, но использует метод GET с той же «Авторизацией»:Основной V1M6 "заголовок.
Кто-нибудь может объяснить, где я ошибаюсь в своем коде?
Заранее спасибо!
ОБНОВЛЕНИЕ .Я нашел, почему это случилось.Транспорт ksoap2 передает (через класс HttpURLConnection) HTTP-заголовки сервера маленькими буквами, но сервер (иногда) ожидает каждого из них с заглавной начальной буквой.И я не могу понять (не могу найти в исходниках), почему и где HttpURLConnection делает его маленьким.
ОБНОВЛЕНИЕ 2 .После моего расследования я могу утверждать, что эта проблема касается ядра Android-версий в версии 2.2 (и, возможно, более старой), но не самой ksoap2-android.У Android 2.3 такой проблемы нет - он отправляет заголовки в необходимом случае, а также работает класс аутентификатора (см. Раздел HTTP-аутентификация HttpURLConnection у разработчиков Android), которые не позволяют использовать обходные методы, такие какиспользуется в коде выше для аутентификации.