问题
I am trying to connect my Android APP development to a Web Service and cannot seem to capture the response (throws the above error); the snippet of my APP code, follows:
@Override
protected String doInBackground(String... params) {
String URL = "https://MyDomain/Services/AccountManager.asmx";
String NAMESPACE = "http://tempuri.org/";
String METHOD_NAME = parameters.get("METHOD_NAME");
String ReturnValue;
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
// addProperty for each KeyPair in the Parameters HashMap
for (Map.Entry<String, String> parameter : parameters.entrySet()) {
if (!parameter.getKey().startsWith("_") && parameter.getKey() != "METHOD_NAME") {
request.addProperty(parameter.getKey() , parameter.getValue());
}
}
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.implicitTypes = true;
envelope.setOutputSoapObject(request);
HttpTransportSE httpTransportSE = new HttpTransportSE(URL);
try {
httpTransportSE.call(NAMESPACE + METHOD_NAME, envelope);
SoapPrimitive soapPrimitive = (SoapPrimitive) envelope.getResponse();
ReturnValue = soapPrimitive.getAttribute("StatusCode").toString();
} catch (Exception ex) {
ReturnValue = "Error: " + ex.getMessage();
}
return ReturnValue;
}
The error is thrown by the line
SoapPrimitive soapPrimitive = (SoapPrimitive) envelope.getResponse();
I read a number of articles/posts which suggests changing the previous line, to the following line:
Object soapPrimitive = (Object) envelope.getResponse();
Whilst this does "workaround" the error, the return values from the service are then unnamed:
- OK
- 2119100
- 278
- E
... rather than, being in a usable "pairing";
response.getAttribute("AccountNumber") = 2119100
response.getAttribute("AccountBalance") = 278
response.getAttribute("StatusCode") = "E"
I do have control of the Web Service, so it's possible to make edits there, if that's the solution; a snippet of the C# code for the service:
[WebMethod(
Description = "Account Lookup",
MessageName = "Account",
EnableSession = false)]
public string Account(
string PostCode,
string Surname,
out double? AccountBalance,
out string AccountNumber,
out string StatusCode)
{
// MY STUFF HERE
AccountBalance = 50;
AccountNumber = 123456;
StatusCode = "A";
Return "OK";
}
The above is a significantly cut-down version of the actual service, which (for production) would return [for example] a complete breakdown of a financial transaction, with the opening balance, current balance, VAT, interest, discounts, etc., so keeping track of an unnamed indexed list will gradually become a maintenance nightmare.
[edit 22/02/2019]
I have changed (and simplified)the WebService so that it ONLY takes the INPUT values
[WebMethod(
Description = "Account Lookup",
MessageName = "Account",
EnableSession = false)]
public string Account(
string PostCode,
string Surname)
.. and from within that method, I make the more in-depth call to a private method that handled the "out" parameters. The WebMethod then turns those parameters into a JSON string and return it. This (rather ugly method) worked, until I wanted to return an array of data, which dropped straight back to the original error.
... next step (as I cannot locate a working solution) will be to try the same with and XML response.
回答1:
It could be that envelope.getResponse()
call returns a collection of SoapPrimitive
s.
Try something like
Vector responseVector = (Vector) envelope.getResponse();
for (Vector res : responseVector) {
SoapPrimitive soapPrimitive = (SoapPrimitive) res;
// your code here using soapPrimitives
}
If the type of elements is still different than SoapPrimitive
, there will be a new Exception
and you can cast accordingly.
来源:https://stackoverflow.com/questions/54712547/java-lang-classcastexception-java-util-vector-cannot-be-cast-to-org-ksoap2-seri