I have a problem when access to WSDL resource with basic authentication from android.
Code:
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");
}
}
}
On androidHTTPTransport.call() I got an exception. Server returns an answer "Access is denied". But as I can see in debug androidHTTPTransport.connection.connection.reqHeader.props "autorization" header is already here: [user-agent, kSOAP/2.0, content-type, text/xml, connection, close, content-length, 330, authorization, Basic V1M6] But in re开发者_运维技巧sHeader I got "HTTP/1.1 401 Authorization Required".
When I trying to open URL in browser - it works fine, but it use GET method with the same "Authorization: Basic V1M6" header.
Can anybody explain where I'm wrong in my code?
Thank you in advance!
UPDATE. I found why it happend. ksoap2 transport gives (via HttpURLConnection class) to server http headers in small letters, but server (sometimes) expect each of it with capital initial letter. And I can't understand (can't find in source codes) why and where HttpURLConnection makes it small.
UPDATE 2. After my investigation I can assert that this problem concern to core Android libs on version 2.2 (and, may be, older) but not to ksoap2-android itself. Android 2.3 have no this issue - it send headers in needed case, and also have Authenticator class worked (see HTTP Authentication section of HttpURLConnection at Android Developers) which prevent from using workaround methods like used in the code above for authentication.
After my investigation I can assert that this problem concern to core Android libs of version 2.2 (and, may be, older) but not to ksoap2-android itself. Android 2.3 have no this issue - it send headers in needed case, and also have Authenticator class worked (see HTTP Authentication section of HttpURLConnection at Android Developers) which prevent from using workaround methods like used in the code above for authentication.
you got an XmlPullParserException because may be you are using earlier version, please switch ksoap's 2.5.7 version and will not get this kind of exception.
I found this in ksoap2 coding tips&tricks. It says you should use "use the class HttpTransportBasicAuth from the extras package".
I change api version 8 to 10, solved this problem.
AndroidManifest.xml:
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="10" />
精彩评论