I am consuming a .net web service using ksoap2 but getting the following Exception:
org.xmlpull.v1.XmlPullParserException: unexpected type (position:END_DOCUMENT null#1:1 in java.io.InputStreamReader#412caa08)`
My request dump is the same as I needed but I'm not getting response dump and it has come as null. I am trying, but getting the same error.Please some one help me. My code is given below-
public class Login extends Activity {
private final String NAMESPACE = "http://xyz.public/imageupload/1.0/";
private final String URL = "http://public.service.xyz.com/ImageUpload.svc";
private final String SOAP_ACTION = "http://xyz.public/imageupload/1.0/Services/Authentication";
private final String METHOD_NAME = "Authentication";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
}
SoapSerializationEnvelope envelope = null;
SoapObject request = null;
HttpTransportSE httpTransportSE = null;
try {
request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("userId", "admin");
request.addProperty("password", "password");
envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
envelope.dotNet = true;
envelope.encodingStyle = SoapSerializationEnvelope.ENC;
/**
* below code for custom header
*/
Element actionElement = new Element().createElement(null,
"d:Action");
actionElement.setAttribute("", "s:mustUnderstand", "1");
actionElement.addChild(Node.TEXT, SOAP_ACTION);
Element toElement = new Element().createElement(null, "d:To");
toElement.setAttribute("", "s:mustUnderstand", "1");
toElement.addChild(Node.TEXT, URL);
Element[] header = { actionElement,toElement };
envelope.headerOut = header;
envelope.env = "http://schemas.xmlsoap.org/soap/envelope/";
/**
* Custom header part end
*/
envelope.setOutputSoapObject(request);
httpTransportSE = new HttpTransportSE(URL);
httpTransportSE.debug = true;
httpTransportSE.call(SOAP_ACTION, envelope);
SoapObject result = (SoapObject) envelope.getResponse();
// To get the data.
String textResult = result.toString();
Log.i("textResult", textResult);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
Log.e("Exception:", e.toString());
}
finally {
Log.i(getClass().getSimpleName(), "requestDump : "+ httpTransportSE.requestDump);
Log.i(getClass().getSimpleName(), "responseDump : "+ httpTransportSE.responseDump);
}
}
}
Related
I am trying to currently pull some xml from a SOAP server to use in my app. I have successfully pulled one object from the server, but cannot pull another object. The first object I pull is a user's ID number. Here is the code I am using to pull the first ID number:
public class logInTask extends AsyncTask<String, Void, String> {
private static final String SOAP_ACTION = "";
private static final String METHOD_NAME = "checkUserLogin";
private static final String NAMESPACE = "http://m";
private static final String URL = "-sensitive information here, just know that this ends with .cfc?wsdl-";
#Override
public String doInBackground(String... strings) {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("usr", strings[0]);
request.addProperty("pwd", strings[1]);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
// SoapPrimitive resultsRequestSOAP = (SoapPrimitive) envelope.getResponse();
SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
RESULT = resultsRequestSOAP.toString();
return RESULT;
} catch (Exception e) {
System.out.println("Error" + e);
return "NULL";
}
}
protected void onPostExecute(String result){
if(RESULT.contains("Password Incorrect")) {
alertDialog("Your password is incorrect. Please try again.");
} else if(RESULT.contains("User Not Found")) {
alertDialog("You have entered a non-existing username/email. Please try again.");
} else {
Log.i("BEGINNINGRESULT", RESULT);
RESULT = RESULT.substring(64);
RESULT = RESULT.substring(0, RESULT.indexOf(";"));
alertDialog(RESULT);
startNewIntent(RESULT);
}
}
}
With this code, I receive a response from the server in the form of a string:
checkUserLoginResponse{checkUserLoginReturn=User Authenticated: 3; }
Now, I go over to another class for a Main Menu esque activity. Here, I am going to use the integer from the above string (3) and feed that into another SOAP request. Here is the code for that:
public class getUserRegistrations extends AsyncTask<String, Void, String> {
private static final String SOAP_ACTION = "";
private static final String METHOD_NAME = "getUserRegistrations";
private static final String NAMESPACE = "http://m";
private static final String URL = "-same url-";
#Override
public String doInBackground(String... userNumber) {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo user = new PropertyInfo();
user.setName("usr");
user.setValue(userNumber);
user.setType(String.class);
request.addProperty(user);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject resultsRequestSOAP = (SoapObject) envelope.getResponse();
androidHttpTransport.responseDump = requestDump;
MainMenuActivity.registrationsGrabbed = resultsRequestSOAP.toString();
return MainMenuActivity.registrationsGrabbed;
} catch (Exception e) {
System.out.println("Error" + e);
return "NULL";
}
}
protected void onPostExecute(String result) {
Log.i("userID", userID);
Log.i("dump", requestDump);
//Log.i("Registration XML:", registrationsGrabbed);
}
}
When I run the app and log in, I successfully pass the userID (userNumber in the second class) and try to pass this to the server. But, I encounter an error. In the logcat output, I see:
09-04 15:23:25.313 28519-28519/co.cdat.emi E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: co.cdat.emi, PID: 28519
java.lang.NullPointerException: println needs a message
and this crashes the app. The error comes from the lines:
Log.i("dump", requestDump);
//Log.i("Registration XML:", registrationsGrabbed);
I'm assuming these errors tell me that there is no response from the server, even though I am sending the same type of request. Could anyone tell me what I'm doing wrong? If you need more information, please ask. Thank you.
I'm using HttpsTransportSE for calling webservices. Repeatedly calling web service which needs for reply 1-2s. Then there is a call which requires 30-45s or return timeout(set on 45s). This problem occurs only on 3G signal on WIFI works perfectly.
public SoapObject CallWS(Object object, ArrayList<Tuples> params,
String SOAP_ACTION, String METHOD_NAME, String NAMESPACE, String serviceURL) {
SoapObject response = null;
//try {
// Generate soap object with WS-namespace and WS-method name
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
// Parameters for WS method
for (int i = 0; i < params.size(); i++) {
request.addProperty(params.get(i).getLeft().toString(), params
.get(i).getRight().toString());
}
// Create soap envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
envelope.headerOut = new Element[1];
envelope.headerOut[0] = buildAuthHeader(NAMESPACE,"trak8","g3s0");
// Add mapping for complex parameter
envelope.addMapping(NAMESPACE, "Object", new Object().getClass());
TrustManagerManipulator.allowAllSSL();
Log.i("NAMESPACE",NAMESPACE);
Log.i("METHOD_NAME",METHOD_NAME);
Log.i("URL2",serviceURL);
//HttpTransportSE aht = new HttpTransportSE(serviceURL, 10000);
String[] serviceURLSplit = serviceURL.split("//");
String[] serviceURLSplitMethod = serviceURLSplit[1].split("/");
HttpsTransportSE aht = new HttpsTransportSE(serviceURLSplitMethod[0], 443,"/"+serviceURLSplitMethod[1], 45000);
List<HeaderProperty> headerList = new ArrayList<HeaderProperty>();
headerList.add(new HeaderProperty("Connection", "keep-alive"));
try {
Log.i("StatusCall", "calling ws"+METHOD_NAME); // For debbug only
aht.call(SOAP_ACTION, envelope,headerList);
response = (SoapObject) envelope.getResponse();
Log.i("StatusCall", "response successfully recived"); // For debbug
// only
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
`
I have a webservice with this location:
<wsdlsoap:address location="http://app.example.com:8080/WSTest/services/Hello"/>
And I want to get access to this webservice over my Android app. I do this:
private class ConnectTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
private final String NAMESPACE = "http://ws.audiomobil.com";
private final String URL = "http://app.example.com:8080/WSTest/services/Hello?wsdl";
private final String SOAP_ACTION = "http://ws.audiomobil.com/hello";
private final String METHOD_NAME = "hello";
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
String firstName = "Android";
String lastName = "Program";
/*
// Pass value for fname variable of the web service
PropertyInfo fnameProp = new PropertyInfo();
fnameProp.setName("fname"); // Define the variable name in the web service method
fnameProp.setValue(firstName); // Define value for fname variable
fnameProp.setType(String.class); // Define the type of thevariable
request.addProperty(fnameProp); // Pass properties to thevariable
// Pass value for lname variable of the web service
PropertyInfo lnameProp = new PropertyInfo();
lnameProp.setName("lname");
lnameProp.setValue(lastName);
lnameProp.setType(String.class);
request.addProperty(lnameProp);
*/
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL,60000);
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
String s = response.toString();
System.out.println("WS: " + s);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
return null;
}
}
++++++EDIT
My Webservice class is this:
public class Hello {
public String hello(String fname, String lname){
return "Hello";
}
}
+++++++
When I run this on my AVD Emulator Android 4.0.3 then its working fine. Its get access to webservice and I get the response.
But when I run it on my device Version 4.0.3, then it's not working. It stops at this point: androidHttpTransport.call(SOAP_ACTION, envelope);
And it throws a XMLPullParserException. Heres the logcat:
01-23 11:24:36.959: I/System.out(8172): org.xmlpull.v1.XmlPullParserException:
unterminated entity ref (position:TEXT #1:86 in java.io.InputStreamReader#4188c258)
I have really no idea how this can happen. Can anyone help me pls?
I think you are missing the xml version tag. Try to set xml version tag before calling
androidHttpTransport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
androidHttpTransport.call(SOAP_ACTION, envelope);
Sample Code:
public static String webServiceForScriptTimeLimit() {
String scriptTimeLimitResponse = null;
try {
SoapObject request = new SoapObject(NAMESPACE,
SCRIPT_TIMELIMIT_METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.implicitTypes = true;
envelope.enc = SoapSerializationEnvelope.ENC2003;
envelope.xsd = SoapEnvelope.XSD;
envelope.xsi = SoapEnvelope.XSI;
envelope.setOutputSoapObject(request);
envelope.setAddAdornments(false);
HttpTransportSE ht = new HttpTransportSE(SOAP_ADDRESS);
ht.debug = true;
ht.call(SOAP_ACTION_TIME_LIMIT, envelope);
final SoapPrimitive response = (SoapPrimitive) envelope
.getResponse();
scriptTimeLimitResponse = response.toString();
}
catch (Exception ex) {
FileLog.logInfo(
"Exception ---> WS_ERROR ---> WebServiceUtility: webServiceForScriptTimeLimit() - "
+ ex.toString(), 0);
}
return scriptTimeLimitResponse;
}
This is my primitive web-service:
#Override
public boolean LogOn(String UserName, String Password) {
String username = "";
String password = "";
if (UserName != null) {
username = UserName;
}
if (Password != null) {
password = Password;
}
System.out.println("username is"+username);
System.out.println("password is"+password);
//test parameters
if (username.equals("admin") && password.equals("admin")) {
return true;
} else {
return false;
}
}
This client on Android:
private static final String METHOD_NAME = "LogOn";
private static final String NAMESPACE = "http://calculator.me.org/";
private static final String URL = "http://10.0.2.2:8080/logon/WebServiceImplService?wsdl";
#Override
protected Integer doInBackground(String... params) {
// TODO Auto-generated method stub
try
{
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//Add the input variables for the method
request.addProperty("username", "admin");
request.addProperty("password","admin");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
System.setProperty("http.keepAlive", "false");
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug=true;
androidHttpTransport.call(getSoapAction(METHOD_NAME), envelope);
SoapObject result = (SoapObject) envelope.bodyIn;
//get response from web server
String d =result.getProperty("return").toString();
// Logging the raw request and response (for debugging purposes)
Log.d(TAG, "HTTP REQUEST:\n" + androidHttpTransport.requestDump);
Log.d(TAG, "HTTP RESPONSE:\n" + androidHttpTransport.responseDump);
Log.i(TAG,"response from service:"+d);
if(d.equals("true"))
{
//The result will be here, use it wisely :)
return 1;
}
else
return 0;
} catch (Exception e) {
Log.e(TAG,"doInBackground failed"+e);
e.printStackTrace();
return 0;
}
}
When i'm manual testing web-service, log web-service:
INFO: username isadmin
INFO: password isadmin
When i'm trying login from android client, i'm get next log:
INFO: username is
INFO: password is
If i'm delete nullpointer check, on web-service i'm get NullPointerException.
Logs from Android client:
11-12 02:29:55.081: D/SmsSender:LogOnAsync(1878): HTTP REQUEST:
11-12 02:29:55.081: D/SmsSender:LogOnAsync(1878): <v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/"><v:Header /><v:Body><n0:LogOn id="o0" c:root="1" xmlns:n0="http://calculator.me.org/"><username i:type="d:string">admin</username><password i:type="d:string">admin</password></n0:LogOn></v:Body></v:Envelope>
11-12 02:29:55.081: D/SmsSender:LogOnAsync(1878): HTTP RESPONSE:
11-12 02:29:55.081: D/SmsSender:LogOnAsync(1878): <?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:LogOnResponse xmlns:ns2="http://calculator.me.org/"><return>false</return></ns2:LogOnResponse></S:Body></S:Envelope>
11-12 02:29:55.081: I/SmsSender:LogOnAsync(1878): response from service:false
What's wrong?
I have a similar problem. I'm decided to read:
Override
protected Integer doInBackground(String... params) {
// TODO Auto-generated method stub
try
{
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo pi1 = new PropertyInfo();
pi1.setName("arg0");
pi1.setValue("admin");
pi1.setType(String.class);
request.addProperty(pi1);
PropertyInfo pi2 = new PropertyInfo();
pi2.setName("arg1");
pi2.setValue("admin");
pi2.setType(String.class);
request.addProperty(pi2);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
System.setProperty("http.keepAlive", "false");
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug=true;
androidHttpTransport.call(getSoapAction(METHOD_NAME), envelope);
SoapObject result = (SoapObject) envelope.bodyIn;
//get response from web server
String d =result.getProperty("return").toString();
// Logging the raw request and response (for debugging purposes)
Log.d(TAG, "HTTP REQUEST:\n" + androidHttpTransport.requestDump);
Log.d(TAG, "HTTP RESPONSE:\n" + androidHttpTransport.responseDump);
Log.i(TAG,"response from service:"+d);
if(d.equals("true"))
{
//The result will be here, use it wisely :)
return 1;
}
else
return 0;
} catch (Exception e) {
Log.e(TAG,"doInBackground failed"+e);
e.printStackTrace();
return 0;
}
}
This will help only if you brought the whole method LogOn
Im trying to use ksoap2 with a webservice in android but I think i cannot get a respond from the webservice. Anyone knows why i get this error?
"org.xmlpull.v1.XmlPullParserException: expected: START_TAG"
my code is:
public class ANDROIDsapActivity extends Activity {
/** Called when the activity is first created. */
private static final String NAMESPACE = "urn:sap-com:document:sap:soap:functions:mc-style";
private static final String URL = "http://192.168.2.5:8000/sap/bc/srt/wsdl/bndg_E0DFBFD4F407C3F1A6A000155D02060A/wsdl11/allinone/ws_policy/document?sap-client=500";
private static final String SOAP_ACTION = "zws_get_customer";
private static final String METHOD_NAME = "ZfGetCustomers";
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView) findViewById(R.id.textView1);
SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
Request.addProperty("IM_NAME","M");
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapEnvelope.setOutputSoapObject(Request);
soapEnvelope.encodingStyle = SoapSerializationEnvelope.ENC2003;
soapEnvelope.bodyOut = Request;
soapEnvelope.dotNet = true;
soapEnvelope.encodingStyle = SoapSerializationEnvelope.XSD;
// AndroidHttpTransport aht = new AndroidHttpTransport(URL);
HttpTransportSE aht = new HttpTransportSE(URL);
aht.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
List<HeaderProperty> headers = new ArrayList<HeaderProperty>();
headers.add(new HeaderProperty("Authorization", "basic " +
Base64.encode("username:password".getBytes())));
try {
aht.call(SOAP_ACTION, soapEnvelope,headers);
SoapPrimitive resultString = (SoapPrimitive) soapEnvelope.getResponse();
tv.setText("Status: " + resultString);
} catch (Exception e) {
// TODO: handle exception
tv.setText(e.toString());
}
}
}
my complete error is :
org.xmlpull.v1.XmlPullParserException: expected: START_TAG
{http://schemas.xmlsoap.org/soap/envelope/} Envelope
(position:START_TAG <{http://schemas.xmlsoap.org/wsdl/}wsdl:definitions
targetNamespace='urn:sap-com:document:sapsoap:functions:mc-style'>
#1:630 in java.io.InputStreamReader#43e50a10
I'm stuck in this error and I cant go any further.
Please help!
EDIT: I HAVE SOLVED THIS. PLEASE READ MY ANSWER BELOW ON COMMENTS AND ANSWERS.
I HOPE I'LL BE HELPFUL FOR SOMEONE IN SOMEWAY.
I have solved my problem by just changing the web service style. Use Restful webservice system instead of SOAP if you want to integrate SAP and android.