1

使用来自 android 的基本身份验证访问 WSDL 资源时出现问题。

代码:

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, content-type, text/xml, connection, close, content-length, 330 , 授权, Basic V1M6] 但是在 resHeader 中我得到了“HTTP/1.1 401 Authorization Required”。

当我尝试在浏览器中打开 URL 时 - 它工作正常,但它使用具有相同“授权:基本 V1M6”标头的 GET 方法。

谁能解释我的代码哪里错了?

先感谢您!

更新。我找到了它发生的原因。ksoap2 传输(通过 HttpURLConnection 类)以小写字母向服务器 http 标头提供,但服务器(有时)期望每个首字母大写。而且我无法理解(无法在源代码中找到)HttpURLConnection 为何以及在何处使它变小。

更新 2。经过我的调查,我可以断言这个问题与 2.2 版(并且可能更旧)上的核心 Android 库有关,但与 ksoap2-android 本身无关。Android 2.3 没有这个问题 - 它会在需要的情况下发送标头,并且还可以使用Authenticator 类(请参阅 Android Developers 的HttpURLConnection的HTTP 身份验证部分),这会阻止使用上述代码中用于身份验证的变通方法。

4

4 回答 4

0

经过我的调查,我可以断言这个问题与 2.2 版(并且可能更旧)的核心 Android 库有关,但与 ksoap2-android 本身无关。Android 2.3 没有这个问题 - 它在需要的情况下发送标头,并且还可以使用Authenticator 类(请参阅 Android Developers 的HttpURLConnection的HTTP 身份验证部分),这会阻止使用上述代码中用于身份验证的变通方法。

于 2011-08-25T13:35:41.637 回答
0

你得到一个 XmlPullParserException 因为可能是你使用的是早期版本,请切换 ksoap 的 2.5.7 版本,不会出现这种异常。

于 2011-09-08T12:31:33.077 回答
0

我在ksoap2 coding tips&tricks中发现了这一点。它说你应该使用“使用额外包中的类 HttpTransportBasicAuth”。

于 2012-12-30T19:29:52.943 回答
-1

我将 api 版本 8 更改为 10,解决了这个问题。

AndroidManifest.xml:

<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="10" />

于 2013-02-27T14:21:19.027 回答