问题
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