How to consume WCF .SVC in Android

╄→尐↘猪︶ㄣ 提交于 2019-12-21 02:53:36

问题


i red a lot of documents about, but i can't consume this .svc file. I've no problem with .ASMX file. Only SVC i'm not able to consume. It's very very very stressfull....! I can't modify WCF part. I post WSDL file and my try to consume it:

WSDL

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
 xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 
 xmlns:tns="http://tempuri.org/" 
 xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
 xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 
 xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
 xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" 
 xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" 
 xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
 xmlns:wsa10="http://www.w3.org/2005/08/addressing" 
 xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" name="ValidateUser_wcf" 
 targetNamespace="http://tempuri.org/">
<wsp:Policy wsu:Id="WSHttpBinding_IValidateUser_wcf_policy">
<wsp:ExactlyOne>
<wsp:All>
<wsaw:UsingAddressing/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://URL/WebServices/validateuser.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://URL/WebServices/validateuser.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IValidateUser_wcf_ValidateUser_InputMessage">
<wsdl:part name="parameters" element="tns:ValidateUser"/>
</wsdl:message>
<wsdl:message name="IValidateUser_wcf_ValidateUser_OutputMessage">
<wsdl:part name="parameters" element="tns:ValidateUserResponse"/>
</wsdl:message>
<wsdl:portType name="IValidateUser_wcf">
<wsdl:operation name="ValidateUser">
<wsdl:input wsaw:Action="http://tempuri.org/IValidateUser_wcf/ValidateUser" message="tns:IValidateUser_wcf_ValidateUser_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IValidateUser_wcf/ValidateUserResponse" message="tns:IValidateUser_wcf_ValidateUser_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="WSHttpBinding_IValidateUser_wcf" type="tns:IValidateUser_wcf">
<wsp:PolicyReference URI="#WSHttpBinding_IValidateUser_wcf_policy"/>
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="ValidateUser">
<soap12:operation soapAction="http://tempuri.org/IValidateUser_wcf/ValidateUser" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ValidateUser_wcf">
<wsdl:port name="WSHttpBinding_IValidateUser_wcf" binding="tns:WSHttpBinding_IValidateUser_wcf">
<soap12:address location="http://URL/WebServices/validateuser.svc"/>
<wsa10:EndpointReference>
<wsa10:Address>
http://URL/WebServices/validateuser.svc
</wsa10:Address>
</wsa10:EndpointReference>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

My Java #1. Simply i've copied xml which come out after sniffed HTTP POST traffic about original .NET client, that i have to replicate in java, with Microsoft .Net Monitor application:

private static final String NAMESPACE = "http://tempuri.org/";
private static final String NAMESPACE_INFOCAD = "http://xxxx.xxx/"; 

private static final String SOAP_ACTION_VALIDATION = "IValidateUser_wcf/ValidateUser";
private static final String VALIDATION_METHOD = "ValidateUser";
private final static String VALIDATION_URI = "http://URL/WebServices/validateuser.svc";

// only a1 node in the header i know, each other is unknown for me. I put them there only because i saw them in soap net client http post
String request = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
        "<s:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">"
        + "<s:Header>"
        //+ "<a:Action s:mustUnderstand=\"1\"> http://tempuri.org/IValidateUser_wcf/ValidateUser </a:Action>"
        + "<a1 xmlns=\"http://xxxx.xxx/\">"+testtoken+"</a1>"
        + "<a:MessageID> urn:uuid:c075fc4e-1e70-48f7-838b-9fa68e7aaad1 </a:MessageID>"
        + "<ActivityId CorrelationId=\"0d4e09eb-5d09-4617-a8e1-ec99415caab5\" xmlns=\"http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics\">"
        + "25adfad8-ab5f-474a-afe3-56941d4ad408"
        + "</ActivityId>"
        + "<a:ReplyTo> http://www.w3.org/2005/08/addressing/anonymous </a:ReplyTo>"
        + "<a:To s:mustUnderstand=\"1\"> http://URL/WebServices/validateuser.svc </a:To>"
        + "</s:Header>"
        + "<s:Body><ValidateUser xmlns=\"http://tempuri.org/\"><username>"+username+"</username><password>"+password+"</password></ValidateUser></s:Body>"
        + "</s:Envelope>";

    String result = CallWebService(VALIDATION_URI, NAMESPACE+VALIDATION_METHOD, request);   



public String CallWebService(String url, String soapAction, String envelope) {  

    final DefaultHttpClient httpClient = new DefaultHttpClient();
    // request parameters
    HttpParams params = httpClient.getParams();
    HttpConnectionParams.setConnectionTimeout(params, 10000);
    HttpConnectionParams.setSoTimeout(params, 15000);
    // set parameter
    HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), true);

    // POST the envelope
    HttpPost httppost = new HttpPost(url);
    // add headers
    httppost.setHeader("soapaction", soapAction);
    httppost.setHeader("Content-Type", "text/xml; charset=utf-8");

    String responseString = "Nothingggg";
    try {

        // the entity holds the request
        HttpEntity entity = new StringEntity(envelope);
        httppost.setEntity(entity);

        // Response handler
        ResponseHandler<String> rh = new ResponseHandler<String>() {
            // invoked when client receives response
            public String handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {

                // get response entity
                HttpEntity entity = response.getEntity();                   

                // read the response as byte array
                StringBuffer out = new StringBuffer();
                byte[] b = EntityUtils.toByteArray(entity);

                // write the response byte array to a string buffer
                out.append(new String(b, 0, b.length));
                return out.toString();
            }
        };

         responseString = httpClient.execute(httppost, rh);

    } catch (Exception e) {
        e.printStackTrace();
        Log.d("me","Exc : "+ e.toString()); 

    }

    // close the connection
    httpClient.getConnectionManager().shutdown();
    return responseString;
}

My Java #2 by Ksoap2. In this case i got this error:

XmlPullParserException: unexpected type 
(position:END_DOCUMENT null@1:1 in 
java.io.InputStreamReader@blablabla)

But i put xml string request in a validation xml application and it's ok:

public String validateUser_WCF(String username, String password){

     String enctoken = TOKEN;
     String testtoken = TestTOKEN;      

     SoapSerializationEnvelope envelope = null;
     SoapObject request = null;
     HttpTransportSE httpTransportSE = null;

     try {
         request = new SoapObject(NAMESPACE, VALIDATION_METHOD);
         request.addProperty("username", username);
         request.addProperty("password", password);

         envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
         envelope.dotNet = true; 
         envelope.setOutputSoapObject(request);

         Element[] header = new Element[2];  
         header[0] = new Element().createElement(NAMESPACE, "To");
         header[0].setName("a1");                 
         header[0].addChild(Node.TEXT, VALIDATION_URI);

         header[1] = new Element().createElement(NAMESPACE_INFOCAD, "a1");                
         header[1].addChild(Node.TEXT, testtoken);

         envelope.headerOut = header;                                 

         httpTransportSE = new HttpTransportSE(VALIDATION_URI);

         httpTransportSE.debug = true;
         //httpTransportSE.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");

         httpTransportSE.call(NAMESPACE+SOAP_ACTION_VALIDATION, envelope);

         String response = (String) envelope.getResponse();
         Log.i("RESPONSE", response);
         return response;  

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally{
             Log.i(getClass().getSimpleName(),"requestDump : "+httpTransportSE.requestDump);
             Log.i(getClass().getSimpleName(),"responseDump : "+httpTransportSE.responseDump);
        }

I really really hope someone can help me. Im arrived in a dead point....


回答1:


I solved by myself (WCF binding has to be basicHttpBinding, otherwise it doesn't work):

private static final String NAMESPACE = "http://tempuri.org/";
private static String URL="your url";

private static final String SOAP_ACTION_VALIDATION = "IValidateUser_wcf/ValidateUser";
private static final String VALIDATION_METHOD = "ValidateUser";

public boolean validateUser_WCF(String username, String password){

    SoapSerializationEnvelope envelope = null;
    SoapObject request = null;
    HttpTransportSE httpTransportSE = null;

    try {
        request = new SoapObject(NAMESPACE, VALIDATION_METHOD);
        request.addProperty("username", username);
        request.addProperty("password", password);

        envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true; 
        envelope.setOutputSoapObject(request);

        //////////////////////////////                               
        // here you can add a HEADER element if you want
        Element[] header = new Element[1];  

        header[0] = new Element().createElement(NAMESPACE_INFOCAD, "a1");                
        header[0].addChild(Node.TEXT, "HeaderTextContent");

        envelope.headerOut = header;
        //////////////////////////////                               

        httpTransportSE = new HttpTransportSE(URL+VALIDATION_URI, 10*10000); // second parameter is timeout
        httpTransportSE.debug = true;
        httpTransportSE.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        httpTransportSE.call(NAMESPACE+SOAP_ACTION_VALIDATION, envelope);

        // if response is a simple text result, you can call SoapPrimitive, if not, you have to call SoapObject result and navigate in response's tree like an xml file
        SoapPrimitive result = (SoapPrimitive)envelope.getResponse();

        //To get the data.
        String textResult = result.toString();
        Log.i("textResult", textResult); 

        return true;

    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }finally{
                // here you can see in LOG what is request you send and what is response received
                Log.i(getClass().getSimpleName(),"requestDump : "+httpTransportSE.requestDump);
                Log.i(getClass().getSimpleName(),"responseDump : "+httpTransportSE.responseDump);
    }

    return false;
}



回答2:


Do you have control over WCF part?

The easiest way will be to update WCF bingding. Currently it is WSHttpBinding, That binding is way more complicated than *.asmx.

Check if it is possible to publish endpoint with basicHttpBinding binding.

http://msdn.microsoft.com/en-us/library/ms731361.aspx

That binding is compatible with *.asmx and you only will need to update URL in your java code to consume it.



来源:https://stackoverflow.com/questions/11160355/how-to-consume-wcf-svc-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!