Cómo consumir WCF .SVC en Android
Redigo muchos documentos, pero no puedo consumir este archivo .svc. No tengo ningún problema con el archivo .ASMX. Sólo SVC no soy capaz de consumir. Es muy muy muy estresante ...! No puedo modificar la parte WCF. Publico el archivo WSDL y trato de consumirlo:
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>
Mi Java # 1. Simplemente copié el XML que aparece después del rastreo de HTTP POST sobre el cliente .NET original, que debo replicar en java, con la aplicación Microsoft .Net Monitor:
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;
}
Mi Java # 2 por Ksoap2. En este caso me sale este error:
XmlPullParserException: unexpected type
(position:END_DOCUMENT null@1:1 in
java.io.InputStreamReader@blablabla)
Pero puse una solicitud de cadena XML en una aplicación XML de validación y está bien:
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);
}
Realmente espero que alguien me pueda ayudar. Llegué a un punto muerto ....