2

WSDL がhttp://srilanka.lk:9080/services/CropServiceProxy?wsdlにある Web サービスにアクセスしようとしています。SoapUI を使用してリクエストを送信し、正常に応答を受け取りました。

次に、KSoap2 for Android を使用して、応答を得ようとしました。しかし、私が得るのは SoapFault エラーだけです。コードは次のとおりです。

文字列 NAMESPACE = "http://schemas.icta.lk/xsd/crop/handler/v1";

    String URL = "http://www.srilanka.lk:9080/services/CropServiceProxy.CropServiceProxyHttpSoap12Endpoint";

    String method_name = "getCropDataList";
    String SOAP_ACTION = method_name;

    SoapObject request = new SoapObject(NAMESPACE, method_name);
    String crop_code_str = String.valueOf(code.getText().toString());
    System.out.println(crop_code_str);
    System.out.println(request.toString());
    request.addProperty("code", crop_code_str );
    System.out.println(request.getProperty("code").toString());

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
    envelope.setOutputSoapObject(request);

    System.out.println("body out : " + envelope.bodyOut.toString());

    HttpTransportSE http_transport  = new HttpTransportSE(URL);
    try {
        http_transport.call(SOAP_ACTION, envelope);
        System.out.println(envelope.bodyIn.toString());

    } catch (Exception e) {
        e.printStackTrace();
        answer.setText("error caught");
    }

これにより、次の結果が得られます。

W/System.err(  394): org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://www.w3.org/2001/12/soap-envelope}Envelope (position:START_TAG <{http://schemas.xmlsoap.org/soap/envelope/}soapenv:Envelope>@1:114 in java.io.InputStreamReader@43e81258)  

VER11で試してみましたが、bodyInとして以下のエラーが出ます。

I/System.out(  365): SoapFault - faultcode: 'soapenv:Server' faultstring: 'org.apache.axis2.databinding.ADBException: Unexpected subelement code' faultactor: 'null' detail: org.kxml2.kdom.Node@43e84648

これは Android 用の Ksoap2 に何か問題がありますか? では、Android で Web サービスを利用する別の方法はありますか? (SOAPのみ利用可能)

更新: コンプレックス型の KvmSerializable インターフェイスを試しました。以下は私のコードです。それでも同じエラーが発生します。XMLPullParser エラーが http_transport.call 行でスローされています。

これは、クライアント側での複合型の実装です。私は WSDL しか持っていません。

public class CropInfo implements KvmSerializable {

    private String name;
    private float price;
    private String location;

    @Override
    public Object getProperty(int arg0) {
        switch (arg0){
        case 0:
            return name;
        case 1:
            return price;
        case 2:
            return location;
        default:
                return null;
        }
    }

    @Override
    public int getPropertyCount() {
        return 3;
    }

    @Override
    public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
        switch (arg0){
        case 0:
            arg2.type = PropertyInfo.STRING_CLASS;
            arg2.name = "Name";
            break;
        case 1:
            arg2.type = Float.class;
            arg2.name = "Price";
            break;
        case 2:
            arg2.type = PropertyInfo.STRING_CLASS;
            arg2.name = "Location";
            break;
        default:
                break;
        }

    }

    @Override
    public void setProperty(int arg0, Object arg1) {
        switch(arg0){
        case 0:
            name = arg1.toString();
            break;
        case 1:
            price = Float.parseFloat(arg1.toString());
        case 2:
            location = arg1.toString();
        default:
            break;
        }
    }
}

Web サービスの応答にアクセスして解析するための変更されたコード。

文字列 NAMESPACE = "http://schemas.icta.lk/xsd/crop/handler/v1/"; 文字列 URL = "http://www.srilanka.lk:9080/services/CropServiceProxy.CropServiceProxyHttpSoap12Endpoint"; String method_name = "getCropDataList"; 文字列 SOAP_ACTION = "http://schemas.icta.lk/xsd/crop/handler/v1/getCropDataList";

    SoapObject soap_request = new SoapObject(NAMESPACE, method_name);
    String crop_code_str = String.valueOf(code.getText().toString());
    System.out.println(crop_code_str);
    System.out.println(soap_request.toString());
    soap_request.addProperty("code", crop_code_str );
    System.out.println(soap_request.getProperty("code").toString());

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
    envelope.setOutputSoapObject(soap_request);
    envelope.addMapping(NAMESPACE, "cropInfo", CropInfo.class);
    //envelope.dotNet=true;

    Marshal floatMarshal = new MarshalFloat();
    floatMarshal.register(envelope);

    System.out.println("body out : " + envelope.bodyOut.toString());

    //AndroidHttpTransport http_transport = new AndroidHttpTransport(URL);
    HttpTransportSE http_transport  = new HttpTransportSE(URL);
    try {
                //error comes from this call            
                http_transport.call(SOAP_ACTION, envelope);


        Vector<CropInfo> result_array = (Vector<CropInfo>)envelope.getResponse();
        if(result_array != null){
            for (CropInfo current_crop: result_array){
                System.out.println(current_crop.getName());
                System.out.println(Float.toString(current_crop.getPrice()));
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
        answer.setText("error caught");
    }
4

3 に答える 3

1

あなたのコードは大丈夫だと思います。

wsdl ファイルを見てみましょう。必要なすべてのデータ (名前空間、アクションなど) がここにあります。多くの場合、アクションは "" のような空の文字列です。私はいつも SoapEnvelope.VER11 を選択していますが、通常は問題ありません。このコードは、kvmSerializable インターフェイスを実装する必要がある複雑なデータが予想される場合、プリミティブ データ型と文字列配列でのみ機能します。

私の悪い英語で申し訳ありませんが、私の意味を理解していただければ幸いです。以下は役立つリンクです。

http://www.drdobbs.com/mobility/208800166;jsessionid=2VAK4K4QQ5H3TQE1GHPSKH4ATMY32JVN?pgno=1

于 2010-12-29T22:40:35.857 に答える
1

KSoap を使用することの苦痛と矛盾について多くのスレッドを読みました。DefaultHttpClient クラスを使用して http ポストを実行し、手動で SOAP ヘッダーを作成して応答を解析するだけです。

于 2010-12-29T19:39:30.133 に答える
0

KSoap には、独自の名前空間を各タグに挿入する傾向があります。これにより、試してみることができる出力が得られます。

envelope.implicitTypes = true;
于 2013-10-13T06:24:36.253 に答える