Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
I am having a lot of trouble finding good information on how to call a standard SOAP/WSDL web service with Android. All I've been able to find are either very convoluted documents and references to "kSoap2" and then some bit about parsing it all manually with SAX. OK, that's fine, but it's 2008, so I figured there should be some good library for calling standard web services.
The web service is just basically one created in NetBeans. I would like to have IDE support for generating the plumbing classes. I just need the easiest/most-elegant way to contact a WSDL based web service from an Android-based phone.
Android does not provide any sort of SOAP library. You can either write your own, or use something like kSOAP 2. As you note, others have been able to compile and use kSOAP2 in their own projects, but I haven't had to.
Google has shown, to date, little interest in adding a SOAP library to Android. My suspicion for this is that they'd rather support the current trends in Web Services toward REST-based services, and using JSON as a data encapsulation format. Or, using XMPP for messaging. But that is just conjecture.
XML-based web services are a slightly non-trivial task on Android at this time. Not knowing NetBeans, I can't speak to the tools available there, but I agree that a better library should be available. It is possible that the XmlPullParser will save you from using SAX, but I don't know much about that.
org.apache.http.impl.client.DefaultHttpClient comes in the Android SDK by default. That'll get you connected to the WSDL.
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://www.example.com/" + URL);
HttpResponse response = httpClient.execute(httpGet, localContext);
It's true that due to it's overhead SOAP is not the best choice for data exchange with mobile devices. However, you might find yourself in situation in which you do not control the format of server output.
So, if you have to stick with SOAP, there is a kSOAP2 library patched for Android here:
http://code.google.com/p/ksoap2-android/
To call a web service from a mobile device (especially on an Android phone), I have used a very simple way to do it. I have not used any web service client API in attempt to call the web service. My approach is as follows to make a call.
Create a simple HTTP connection by
using the Java standard API
HttpURLConnection.
Form a SOAP request. (You can make
help of SOAPUI to make a SOAP
request.)
Set doOutPut flag as true.
Set HTTP header values like
content-length, Content
type, and User-agent. Do not forget
to set Content-length value as it is a mandatory.
Write entire the SOAP request to the output stream.
Call the method to make a connection and
receive the response (In my case I used
getResonseCode).
If your received response code as
It means you are succeeded to call web service.
Now take an input stream on the same
HTTP connection and receive the
string object. This string object is
a SOAP response.
If the response code is other than
200 then take a ErrorInput stream on
same HTTPobject and receive the
error if any.
Parse the received response
using SAXParser (in my case) or
DOMParaser or any other parsing
mechanism.
I have implemented this procedure for the Android phone, and it is successfully running. I am able to parse the response even if it is more than 700 KB.
SOAP is an ill-suited technology for use on Android (or mobile devices in general) because of the processing/parsing overhead that's required. A REST services is a lighter weight solution and that's what I would suggest. Android comes with a SAX parser, and it's fairly trivial to use. If you are absolutely required to handle/parse SOAP on a mobile device then I feel sorry for you, the best advice I can offer is just not to use SOAP.
About a year ago I was reading this thread trying to figure out how to do SOAP calls on Android - the suggestions to build my own using HttpClient resulted in me building my own SOAP library for Android:
IceSoap
Basically it allows you to build up envelopes to send via a simple Java API, then automatically parses them into objects that you define via XPath... for example:
<Dictionary>
<Id></Id>
<Name></Name>
</Dictionary>
Becomes:
#XMLObject("//Dictionary")
public class Dictionary {
#XMLField("Id")
private String id;
#XMLField("Name")
private String name;
}
I was using it for my own project but I figured it might help some other people so I've spent some time separating it out and documenting it. I'd really love it if some of your poor souls who stumble on this thread while googling "SOAP Android" could give it a go and get some benefit.
DON'T FORGET TO ADD ksoap2.jar in your project and also add the
INTERNET permission in AndroidManifest file
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class WebserviceActivity extends Activity {
private static final String NAMESPACE = "https://api.authorize.net/soap/v1/";
private static final String URL ="https://apitest.authorize.net/soap/v1/Service.asmx?wsdl";
private static final String SOAP_ACTION = "https://api.authorize.net/soap/v1/AuthenticateTest";
private static final String METHOD_NAME = "AuthenticateTest";
private TextView lblResult;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lblResult = (TextView) findViewById(R.id.tv);
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("name","44vmMAYrhjfhj66fhJN");
request.addProperty("transactionKey","9MDQ7fghjghjh53H48k7e7n");
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();
// SoapPrimitive resultsRequestSOAP = (SoapPrimitive) envelope.getResponse();
SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
lblResult.setText(resultsRequestSOAP.toString());
System.out.println("Response::"+resultsRequestSOAP.toString());
} catch (Exception e) {
System.out.println("Error"+e);
}
}
}
I had my tryst with KSOAP; I chose a rather simpler approach.
Given a WSDL file, create SOAP Request templates for each Request(for e.g.: using SOAP UI) and then substitute the values to be passed in code. POST this data to the service end point using DefaultHttpClient instance and get the response stream. Parse the Response Stream using an XML Pull parser.
You can have a look at WSClient++
I've created a new SOAP client for the Android platform. It is using a JAX-WS generated interface, but it is only a proof-of-concept so far.
If you are interested, please try the example and/or watch the source at AndroidSOAP.
If you can, go for JSON. Android comes with the complete org.json package
Call ksoap2 methods. It works very fine.
Set up the details, like
private static String mNAMESPACE=null;
private static String mURL=null;
public static Context context=null;
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(Request);
envelope.addMapping(mNAMESPACE, "UserCredentials",new UserCredendtials().getClass());
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(mURL);
and then to get the result do
androidHttpTransport.call(SOAP_ACTION, envelope);
result = (SoapPrimitive)envelope.getResponse();
I hope Calling a web service from Android helps.
Few months ago I was working with jax-ws web service in j2ee application, There we were using CXF wsdl2java to generate WS client stub from the WSDL file and with those client stubs we consumed the web services. Few weeks ago, when I was trying to consume the web service in the same way in android platform I couldn't, because the android jar has not all the "jax-ws" supporting classes in it. That time I didn't find any such tool ( if I wasn't failed to google efficiently) to meet my requirement --
Get the client stub from the WSDL.
And call the Service with some argument (java business request
object).
Get the Response Business Object.
So, I developed my own Android SOAP Client Generation Tool. Where you have to follow these steps :
From WSDL Get WS Client Stub, Put it in your project.
Say for Some Service "ComplexOperationService", Instantiate the
Service, Get the Endpoint port and call the service method, and get the response from the Web service :
eg:
ComplexOperationService service = new ComplexOperationService( );
ComplexOperation port= service.getComplexOperationPort();
SomeComplexRequest request = --Get some complex request----;
SomeComplexResp resp = port.operate( request );
You don't need to care about the service class/req/response classes or any other classes and the method as well, as you know its all are generated from WSDL.
And of course you needn't be aware of the soap action/envelop/namespace etc. Just call the method as we, developers do all the time.
I am sure you could make a little SOAP client with Axis. Axis installation instructions.
I think Call SOAP Web Service from Android application will help you a lot.
Follow these steps by the method SOAP
From the WSDL file,
create SOAP Request templates for each Request.
Then substitute the values to be passed in code.
POST this data to the service end point using DefaultHttpClient instance.
Get the response stream and finally
Parse the Response Stream using an XML Pull parser.
If you can use JSON, there is a whitepaper, a video and the sample.code in Developing Application Services with PHP Servers and Android Phone Clients.
For me the easiest way is to use good tool to generate all required classes. Personally I use this site:
http://easywsdl.com/
It supports quite complex web services and uses ksoap2.
I would suggest checking out a very useful tool that helped me a lot. The guys
who take care of that project were very helpful, too.
www.wsdl2code.com/
If you are having problem regarding calling Web Service in android then
You can use below code to call the web service and get response. Make sure that your the web service return the response in Data Table Format..This code will help you if you using data from SQL Server database. If you using MYSQL you need to change one thing just replace word NewDataSet from sentence obj2=(SoapObject) obj1.getProperty("NewDataSet"); by DocumentElement
void callWebService(){
private static final String NAMESPACE = "http://tempuri.org/"; // for wsdl it may be package name i.e http://package_name
private static final String URL = "http://localhost/sample/services/MyService?wsdl";
// you can use IP address instead of localhost
private static final String METHOD_NAME = "Function_Name";
private static final String SOAP_ACTION = "urn:" + METHOD_NAME;
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("parm_name", prm_value);// Parameter for Method
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;// **If your Webservice in .net otherwise remove it**
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
androidHttpTransport.call(SOAP_ACTION, envelope);// call the eb service
// Method
} catch (Exception e) {
e.printStackTrace();
}
// Next task is to get Response and format that response
SoapObject obj, obj1, obj2, obj3;
obj = (SoapObject) envelope.getResponse();
obj1 = (SoapObject) obj.getProperty("diffgram");
obj2 = (SoapObject) obj1.getProperty("NewDataSet");
for (int i = 0; i < obj2.getPropertyCount(); i++) {
// the method getPropertyCount() and return the number of rows
obj3 = (SoapObject) obj2.getProperty(i);
obj3.getProperty(0).toString();// value of column 1
obj3.getProperty(1).toString();// value of column 2
// like that you will get value from each column
}
}
If you have any problem regarding this you can write me..
This is a working example of consuming SOAP web services in android.
**Note ::***DON'T FORGET TO ADD ksoap2.jar in your project and also add the INTERNET permission in AndroidManifest file*
public final String WSDL_TARGET_NAMESPACE = "http://tempuri.org/";
public final String METHOD_NAME = "FahrenheitToCelsius";
public final String PROPERTY_NAME = "Fahrenheit";
public final String SOAP_ACTION = "http://tempuri.org/FahrenheitToCelsius";
public final String SOAP_ADDRESS = "http://www.w3schools.com/webservices/tempconvert.asmx";
private class TestAsynk extends AsyncTask<String, Void, String> {
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(getApplicationContext(),
String.format("%.2f", Float.parseFloat(result)),
Toast.LENGTH_SHORT).show();
}
#Override
protected String doInBackground(String... params) {
SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE,
METHOD_NAME);
request.addProperty(PROPERTY_NAME, params[0]);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(
SOAP_ADDRESS);
Object response = null;
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
response = envelope.getResponse();
Log.e("Object response", response.toString());
} catch (Exception e) {
e.printStackTrace();
}
return response.toString();
}
}
Please download and add SOAP library file with your project
File Name : ksoap2-android-assembly-3.4.0-jar-with-dependencies
Clean the application and then start program
Here is the code for SOAP service call
String SOAP_ACTION = "YOUR_ACTION_NAME";
String METHOD_NAME = "YOUR_METHOD_NAME";
String NAMESPACE = "YOUR_NAME_SPACE";
String URL = "YOUR_URL";
SoapPrimitive resultString = null;
try {
SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
addPropertyForSOAP(Request);
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapEnvelope.dotNet = true;
soapEnvelope.setOutputSoapObject(Request);
HttpTransportSE transport = new HttpTransportSE(URL);
transport.call(SOAP_ACTION, soapEnvelope);
resultString = (SoapPrimitive) soapEnvelope.getResponse();
Log.i("SOAP Result", "Result Celsius: " + resultString);
} catch (Exception ex) {
Log.e("SOAP Result", "Error: " + ex.getMessage());
}
if(resultString != null) {
return resultString.toString();
}
else{
return "error";
}
The results may be JSONObject or JSONArray Or String
For your better reference,
https://trinitytuts.com/load-data-from-soap-web-service-in-android-application/
Thanks.
You may perform soap call as post over http with certain headers.
I solved this question without additional libraries like ksoap2
Here is live code getting orders from soap service
private static HashMap<String,String> mHeaders = new HashMap<>();
static {
mHeaders.put("Accept-Encoding","gzip,deflate");
mHeaders.put("Content-Type", "application/soap+xml");
mHeaders.put("Host", "35.15.85.55:8080");
mHeaders.put("Connection", "Keep-Alive");
mHeaders.put("User-Agent","AndroidApp");
mHeaders.put("Authorization","Basic Q2xpZW50NTkzMzppMjR3s2U="); // optional
}public final static InputStream receiveCurrentShipments(String stringUrlShipments)
{
int status=0;
String xmlstring= "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:ser=\"http://35.15.85.55:8080/ServiceTransfer\">\n" +
" <soap:Header/>\n" +
" <soap:Body>\n" +
" <ser:GetAllOrdersOfShipment>\n" +
" <ser:CodeOfBranch></ser:CodeOfBranch>\n" +
" </ser:GetAllOrdersOfShipment>\n" +
" </soap:Body>\n" +
"</soap:Envelope>";
StringBuffer chaine = new StringBuffer("");
HttpURLConnection connection = null;
try {
URL url = new URL(stringUrlShipments);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Length", xmlstring.getBytes().length + "");
connection.setRequestProperty("SOAPAction", "http://35.15.85.55:8080/ServiceTransfer/GetAllOrdersOfShipment");
for(Map.Entry<String, String> entry : mHeaders.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
connection.setRequestProperty(key,value);
}
connection.setRequestMethod("POST");
connection.setDoInput(true);
OutputStream outputStream = connection.getOutputStream();
outputStream.write(xmlstring.getBytes("UTF-8"));
outputStream.close();
connection.connect();
status = connection.getResponseCode();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
Log.i("HTTP Client", "HTTP status code : " + status);
}
InputStream inputStream = null;
try {
inputStream = connection.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
return inputStream;
}
To call a SOAP web Service from android , try to use this client
DON'T FORGET TO ADD ksoap2-android.jar in your java build path
public class WsClient {
private static final String SOAP_ACTION = "somme";
private static final String OPERATION_NAME = "somme";
private static final String WSDL_TARGET_NAMESPACE = "http://example.ws";
private static final String SOAP_ADDRESS = "http://192.168.1.2:8080/axis2/services/Calculatrice?wsdl";
public String caclculerSomme() {
String res = null;
SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE,
OPERATION_NAME);
request.addProperty("a", "5");
request.addProperty("b", "2");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE httpTransport = new HttpTransportSE(SOAP_ADDRESS);
try {
httpTransport.call(SOAP_ACTION, envelope);
String result = envelope.getResponse().toString();
res = result;
System.out.println("############# resull is :" + result);
} catch (Exception exception) {
System.out.println("########### ERRER" + exception.getMessage());
}
return res;
}
}
Add Soap Libaray(ksoap2-android-assembly-3.2.0-jar-with-dependencies.jar):
public static String Fn_Confirm_CollectMoney_Approval(
HashMap < String, String > str1,
HashMap < String, String > str2,
HashMap < String, String > str3) {
Object response = null;
String METHOD_NAME = "CollectMoney";
String NAMESPACE = "http://xxx/yyy/xxx";
String URL = "http://www.w3schools.com/webservices/tempconvert.asmx";
String SOAP_ACTION = "";
try {
SoapObject RequestParent = new SoapObject(NAMESPACE, METHOD_NAME);
SoapObject Request1 = new SoapObject(NAMESPACE, "req");
PropertyInfo pi = new PropertyInfo();
Set mapSet1 = (Set) str1.entrySet();
Iterator mapIterator1 = mapSet1.iterator();
while (mapIterator1.hasNext()) {
Map.Entry mapEntry = (Map.Entry) mapIterator1.next();
String keyValue = (String) mapEntry.getKey();
String value = (String) mapEntry.getValue();
pi = new PropertyInfo();
pi.setNamespace("java:com.xxx");
pi.setName(keyValue);
pi.setValue(value);
Request1.addProperty(pi);
}
mapSet1 = (Set) str3.entrySet();
mapIterator1 = mapSet1.iterator();
while (mapIterator1.hasNext()) {
Map.Entry mapEntry = (Map.Entry) mapIterator1.next();
// getKey Method of HashMap access a key of map
String keyValue = (String) mapEntry.getKey();
// getValue method returns corresponding key's value
String value = (String) mapEntry.getValue();
pi = new PropertyInfo();
pi.setNamespace("java:com.xxx");
pi.setName(keyValue);
pi.setValue(value);
Request1.addProperty(pi);
}
SoapObject HeaderRequest = new SoapObject(NAMESPACE, "XXX");
Set mapSet = (Set) str2.entrySet();
Iterator mapIterator = mapSet.iterator();
while (mapIterator.hasNext()) {
Map.Entry mapEntry = (Map.Entry) mapIterator.next();
// getKey Method of HashMap access a key of map
String keyValue = (String) mapEntry.getKey();
// getValue method returns corresponding key's value
String value = (String) mapEntry.getValue();
pi = new PropertyInfo();
pi.setNamespace("java:com.xxx");
pi.setName(keyValue);
pi.setValue(value);
HeaderRequest.addProperty(pi);
}
Request1.addSoapObject(HeaderRequest);
RequestParent.addSoapObject(Request1);
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(
SoapEnvelope.VER10);
soapEnvelope.dotNet = false;
soapEnvelope.setOutputSoapObject(RequestParent);
HttpTransportSE transport = new HttpTransportSE(URL, 120000);
transport.debug = true;
transport.call(SOAP_ACTION, soapEnvelope);
response = (Object) soapEnvelope.getResponse();
int cols = ((SoapObject) response).getPropertyCount();
Object objectResponse = (Object) ((SoapObject) response)
.getProperty("Resp");
SoapObject subObject_Resp = (SoapObject) objectResponse;
modelObject = new ResposeXmlModel();
String MsgId = subObject_Resp.getProperty("MsgId").toString();
modelObject.setMsgId(MsgId);
String OrgId = subObject_Resp.getProperty("OrgId").toString();
modelObject.setOrgId(OrgId);
String ResCode = subObject_Resp.getProperty("ResCode").toString();
modelObject.setResCode(ResCode);
String ResDesc = subObject_Resp.getProperty("ResDesc").toString();
modelObject.setResDesc(ResDesc);
String TimeStamp = subObject_Resp.getProperty("TimeStamp")
.toString();
modelObject.setTimestamp(ResDesc);
return response.toString();
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
I'm trying to call .asmx web service from Android. Below you can see my code. It's working when I use it for another web service but it doesn't work for one I need to use.
The problem is "java.io.IOException:HTTP request failed, HTTP status: 500" exception.
Firstly i assume that the problem is from the web service side. However it works when i try to reach using Devexpress and .NET.
I tried to get same error from Devexpress, when I remove "contentType: "application/json; charset=utf-8"," line.
Note: There is no error at web service definitions.
private class KullaniciServiceAsync extends AsyncTask {
protected void onPreExecute(){
Toast.makeText(getApplicationContext(), "Kullanici Bilgileri Alınıyor...", Toast.LENGTH_SHORT).show();
}
#Override
protected KullaniciBilgisiGetir doInBackground(String... Str) {
try {
//ArrayList<HeaderProperty> headerProperty = new ArrayList<HeaderProperty>();
//headerProperty.add(new HeaderProperty("Content-Type", "application/json; charset=utf-8"));
k = new KullaniciBilgisiGetir();
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("UserId","1234567890");
request.addProperty("Password",Pass);
request.addProperty("Kod",Kod);
request.addProperty("Sifre",Sifre);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
Log.e("Request",request.toString());
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;
try{
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject response = (SoapObject) envelope.getResponse();
if (response.hasProperty("KResult")) {
if (response.getPropertyAsString("KResult") == null) {
k.setKullaniciRespond(null);
} else {
k.setKullaniciRespond(response.getPropertyAsString("KResult"));
}
}
}catch(Exception e){
Log.e("httpTRYCATCH", e.toString());
}
} catch (Exception e) {
Log.e("ilkTRY",e.toString());
}
return k;
}
protected void onPostExecute(KullaniciBilgisiGetir e){
txt1.setText("ResponseText ->" + e.getKullaniciRespond());
//txt2.setText("bu "+e.getResponse());
//txt3.setText("Count "+count);
}
}
java.io.IOEXCEPTION
Signals that an I/O exception of some sort has occurred. This class is
the general class of exceptions produced by failed or interrupted I/O
operations.
The Web server encountered an unexpected condition that prevented it from fulfilling the request by the client for access to the requested URL.
May be something is wrong at the server end, but the server can not be more specific about the error condition in its response.
therefore it returns it as a error code 500 which means there was an error at server end.
chances of getting this error might be
The inputs or values that require to be passed for the method on server side and in your code side are different.
May be your inputs were right but at some point the server failed to process output at his end and given you the response 500
How can it be resolved?
You will have to ask system administrator to check the error log at his end(if any log is used on their side).If the error is logged you will know the exact reason.
please check property names are same with web service parameters.
for example;
request.addProperty("UserId","1234567890");
Is your parameter name UserId on web service ?
also you can follow this tutorial : Android Programlama – .Net Web Service Kullanımı
I am facing a problem to call https from Android. Can any one please help with steps to connect to the https server.
I tried to connect to google with https and its working fine but when I try to connect to my local server, I am facing problems.
want to connect a RESTful web service with https
want to connect a SOAP based web service developed using JAX-WS with https.
Code to connect with RESTFul
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
DefaultHttpClient client = new DefaultHttpClient();
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());
// Set verifier
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
// Example send http request
//final String url = "https://encrypted.google.com/";
final String url = "https://ipaddress:8181/RESTTest/cars";
HttpPost httpPost = new HttpPost(url);
try{
HttpResponse response = httpClient.execute(httpPost);
System.out.println(response);
}catch(Exception e){
e.printStackTrace();
}
its working fine for google but not working for my server and it's giving
javax.net.ssl.SSLException: Not trusted server certificate
Code for connect with SOAP:
public String getString(final String methodName, Map<String, Object> params) throws Exception {
HttpTransportSE httpsTransportSE = new HttpTransportSE("https://ipaddress:8181/BankingWS/banking?wsdl");
try {
SoapObject request = new SoapObject("https://test/",
methodName);
if(params != null && params.size() > 0){
Set<String> keys = params.keySet();
Iterator<String> iterator = keys.iterator();
while(iterator.hasNext()){
String key = iterator.next();
request.addProperty(key, params.get(key));
key = null;
}
}
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
TrustManagerManipulator.allowAllSSL();
httpsTransportSE.call(methodName, envelope);
SoapPrimitive sp = (SoapPrimitive) envelope.getResponse();
return sp.toString();
} catch (Exception exception) {
System.out.println(exception.toString());
throw exception;
}
}
In above code using the TrustManagerManipulator from following link:
http://abhinavasblog.blogspot.com/2011/07/allow-untrusted-certificate-for-https.html
This is also not working and when I check the response code it's giving
SoapFault - faultcode: 'S:Client' faultstring: 'Cannot find dispatch method for {test.WSEndPointPort}authenticate' faultactor: 'null' detail: null
Please help to fix this problem, as I am not able to call https from Android by any way :(
Thank you very much for your time and efforts.
Thank you,
Ishan
You need to create a X509TrustManager which bypass all the security check. You can find an example in this similar questions:
Make a connection to a HTTPS server from Java and ignore the validity of the security certificate
or
How to ignore SSL certificate errors in Apache HttpClient 4.0
I have a standard code to call a .net webservice
I get exception "org.xmlpull.v1.xmlpullparserexception expected start_tag" at line
transportSE.call(SOAP_ACTION,soapSerializationEnvelope);
However, if i call the same webservice from a .NET code i get a well structured proper output as desired.
It primarily seems that from kSOAP2, there is a definite output that it gets but when it goes to parse further w.r.t SoapPrimitive objects, it fails.
So, is there other way to look at the actual output (actual soap envelope) received and then may be parse it myself appropriately.
I'm investigating a similar problem I'm having. Stumbled across this comment
When I use SoapEnvelope.VER11, it works fine, But when I use
SoapEnvelope.VER12, it gives me error:
"org.xmlpull.v1.XmlPullParserException: expected: START_TAG".
http://groups.google.com/group/android-developers/browse_thread/thread/b585862b6e939fd2
Perhaps we are having compatibility issues regarding the soap version. Also connecting to a dot net service you may need to set envelope.dotNet = true; .. but you've probably done that
I was getting this START_TAG Exception but in my case it was because my values for
METHOD_NAME="";
NAMESPACE ="";
SOAP_ACTION ="";
URL ="";
were not correct.
Now How to find out the correct values of these parameters you can Check out my other answer here
SoapObject req = new SoapObject(NAMESPACE,METHOD_NAME);
//SoapObject req = new SoapObject(Namespace_Server,MethodName_Server);
//req.addProperty("ImageData", Base64.encode(data));
req.addProperty("ImageData", data);
req.addProperty("login", CommonStaticData.getusername());
req.addProperty("password",CommonStaticData.getpassword());
req.addProperty("recipeId",FileID);
MarshalBase64 mbase = new MarshalBase64();// marshal is used to serialize the byte array
SoapSerializationEnvelope envelop = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelop.bodyOut = req;
envelop.encodingStyle = SoapSerializationEnvelope.ENC2001;
envelop.dotNet = true;
envelop.setOutputSoapObject(req);
HttpTransportSE aht = new HttpTransportSE(URL);
mbase.register(envelop);
aht.call(SOAP_ACTION,envelop);
Well now that I've solved my original problem hit this one!
I found that ksoap2 couldn't parse the response... specifically org.kxml2.io.KXmlParser.require(type, namespace, name) threw the following exception.
WARN/System.err(2330): org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://www.w3.org/2001/12/soap-envelope}Envelope (position:START_TAG <h1>#1:4 in java.io.InputStreamReader#47ff3050)
Note that h1 tag. That comes from <h1>404 Not Found</h1> ... so yes, be aware your response may be from a website but not your web service :)
Hope that helps someone one day
I had almost the same error, my exception was this "position:START_TAG #2:7"
but I've fixed because I was naming in a wrong way a parameter, the name must be exactly as is specified on the XSD.
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("arg0_java_lang_String", "Club");
in the addPropery method I was using a wrong parameter name.
After making sure the url of webservice is reachable by using the below code by watching variable urlc.getResponseCode() for response code while altering the ip from localhost ,fixed ,external and finally to 10.0.2.2
public static boolean isNetworkAvailable() {
//http://stackoverflow.com/questions/1560788/how-to-check-internet-access-on-android-inetaddress-never-timeouts/4009133#comment24565402_4009133
/* ConnectivityManager cm =
(ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {//netInfo.isConnectedOrConnecting()
return true;
}
return false;*/
//http://stackoverflow.com/questions/5474089/how-to-check-currently-internet-connection-is-available-or-not-in-android?rq=1
boolean connected = false;
ConnectivityManager connectivityManager = (ConnectivityManager)_context.getSystemService(Context.CONNECTIVITY_SERVICE);
if(connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED ||
connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED) {
//we are connected to a network
connected=true;
return connected;
}
else
{
connected=false;
return false;
}
}
public static boolean hasActiveInternetConnection() {
if (isNetworkAvailable()) {
try {
//String url = "http://www.google.com",
String url = "http://10.0.2.2:8089/UNIV_AXIS_DYN_WEB/services/ServiceMethods?wsdl",
proxy = "proxy.rss.jo",
port= "8080";
URL server = new URL(url);
Properties systemProperties = System.getProperties();
/*systemProperties.setProperty("http.prosyHost",proxy);
systemProperties.setProperty("http.prosyHost",port);*/
HttpURLConnection urlc = (HttpURLConnection) (server.openConnection());
urlc.setRequestProperty("User-Agent", "Test");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(500);
urlc.connect();
System.out.println(urlc.getResponseCode());
return (urlc.getResponseCode() == 200);
} catch (IOException e) {
Log.e(LOG_TAG, "Error checking internet connection", e);
return false;
}
} else {
Log.d(LOG_TAG, "No network available!");
return false;
}
}
For me i got this hint "not the missing character s in the below"
[ERROR] Exception occurred while trying to invoke service method login
org.apache.axis2.AxisFault: namespace mismatch require http://services.univ.rss found http://service.univ.rss
The rest of log tomcat etc
at org.apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.java:190)
at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:117)
at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:114)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:146)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Unknown Source)
And yes after tracing the LogCat i did not check th tomcat server log eve if the service was tested by SoapUi successfully , you should monitor all logs in every change test , i even forgot at first to start the database service so be carefull :)
The Soap Call
public SoapObject SoapCall(Vector<PropertyInfo> propertyInfo)
{
Integer parametersSize = propertyInfo.size();
//Initialize soap request + add parameters
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
for(int i=0;i<parametersSize;i++)
{
request.addProperty(propertyInfo.get(i));
}
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
//envelope.dotNet = false; if service of type asmx .NET
envelope.setOutputSoapObject(request);
Log.d("App Log c ","c");
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
System.out.println(androidHttpTransport.getPort());
// Make the soap call.
//this is the actual part that will call the webservice
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
//Log.i("App Log 1 ", response.toString());
} catch (Exception e) {
e.printStackTrace();
}
// Get the SoapResult from the envelope body.
SoapObject result = (SoapObject)envelope.bodyIn;
Log.i("App Log 2 ", result.toString());
Log.i("App Log 2 ", result.getProperty(0).toString());
return result;
}
Vector<PropertyInfo> vectorProperyInfo = new Vector<PropertyInfo>();
PropertyInfo userProp = new PropertyInfo();
userProp.setName("userName");
userProp.setValue(username);
userProp.setType(String.class);
vectorProperyInfo.addElement(userProp);
PropertyInfo passProp = new PropertyInfo();
passProp.setName("pass");
passProp.setValue(password);
passProp.setType(String.class);
vectorProperyInfo.addElement(passProp);
SoapObject result = soapUtil.SoapCall(vectorProperyInfo);
if (result != null && result.getProperty(0).toString().equals("1")) {
return "LOGIN_SUCCESS";// for a student
}
P.S My Db Is Oracle and webservice is soap and used axis2-1.2 bin And tested on Android 4.0 the above error response code was 500 Internal Error