I wrote a simple webservice in Delphi XE
It is running on IIS, as ISAPI Dll.
I cant connect to this webservice with Android:
private final String NAMESPACE = "http://217.114.221.83/grigliamo/";
private final String URL = "http://217.114.221.83/grigliamo/DifferenziaWS.dll/wsdl/IWSDifferenzia";
private final String SOAP_ACTION = "http://217.114.221.83/grigliamo/WS_Login";
private final String METHOD_NAME = "WS_Login";
public void getWebService(String x) {
//Create request
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
//Involve web service
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
Assign it to fahren static variable
Res = response.toString();
} catch (Exception e) {
Res = e.toString();
e.printStackTrace();
}
}
I always get an org.xmlpull.v1.XmlPullParserException: expectd START_TAG
Can anybody tell me what's wrong on my webservice please?
Thanks
Andrea
Nothing is wrong with the web service, SoapUI can retrieve the WSDL and send login requests.
I recommend to read ksoap2 org.xmlpull.v1.xmlpullparserexception expected start_tag error
The answers there contain step-by-step guides to build the correct SOAP request parameters / properties for a web service.
Related
I'm new in android development and I'm developing an application that can get data from web service. For example I created a login on my android application and the data that will going to input their is from the web service. How can I do it and what is the easiest way to do it using JSON or SOAP? Please provide some example so I'm going to have an idea how to do this thanks.
Here is a good example for this, im using something similar:
enter link description here
private final String NAMESPACE = "http://tempuri.org/";
private final String URL = "http://www.w3schools.com/webservices/tempconvert.asmx";
private final String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit";
private final String METHOD_NAME = "CelsiusToFahrenheit";
public void getFahrenheit(String celsius) {
//Create request
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//Property which holds input parameters
PropertyInfo celsiusPI = new PropertyInfo();
//Set Name
celsiusPI.setName("Celsius");
//Set Value
celsiusPI.setValue(celsius);
//Set dataType
celsiusPI.setType(double.class);
//Add the property to request object
request.addProperty(celsiusPI);
//Create envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
//Set output SOAP object
envelope.setOutputSoapObject(request);
//Create HTTP call object
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
//Invole web service
androidHttpTransport.call(SOAP_ACTION, envelope);
//Get the response
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
//Assign it to fahren static variable
fahren = response.toString();
} catch (Exception e) {
e.printStackTrace();
}
}
For JSON check this tutorial.
For SOAP check this.
Json is the most simple and clean communication protocol. I would suggest using a library for getting the data https://github.com/kodart/Httpzoid
There are some usage samples.
I think this is a simple problem that others may be able to provide the missing link to. I have a Workflow wcf service that my .NET clients can communicate with properly. I have turned on tracing under the appfabric and can watch service calls execute properly so I feel comfortable the service is not the problem. My Android calls never hit the first trace point.
In Android using ksoap2 (2.6.5) when I call this line I get an Object reference not set error:
SoapObject response = (SoapObject)envelope.getResponse();
To me this seems simple the envelope must be null and when we try to access it to exec the getResponse we have our error and yet in the debugger it shows it as a valid object. Furthermore, I can't find the documentation to explain and every tutorial I have seen has it this way so....?
One thing that is different is that in .NET I would create an object pass the object letting .NET serialize it for me. Here I add several parameters and they are all strings but the enum I will show as it is a possible culprit. Here is my full Java implementation:
String NAMESPACE = "http://tempuri.org/";
String METHOD_NAME = "LiftDataExchange";
String SOAP_ACTION = "http://tempuri.org/ILiftDataExchange/ProcessDataRequest";
String URL = "http://www.icyarmtesting.com/LiftDataExchange.xamlx";
String SOAP_REMOTE_NAMESPACE = "http://schemas.datacontract.org/2004/07/IronMikeDataExchangeWorkflowService.Enum";
String X = "";
ExchangeEnumerations ExrcsEnum = ExchangeEnumerations.GetNextWorkout;
//Initialize soap request
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//add parameters
PropertyInfo piAct = new PropertyInfo();
piAct.setName("Action");
piAct.setValue(ExrcsEnum);
piAct.setType(ExchangeEnumerations.class);
request.addProperty(piAct);
//Declare the version of the SOAP request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.addMapping(SOAP_REMOTE_NAMESPACE, "ExchangeEnumerations", ExchangeEnumerations.class, ExchangeEnumerationsEnumClass.getInstance());
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
//Needed to make the internet call
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;
try
{
//this is the actual part that will call the webservice
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject response = (SoapObject)envelope.getResponse();
X = response.getProperty(0).toString();
}
catch (Exception e)......
Here is my request dump:
<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>
<LiftDataExchange xmlns="http://tempuri.org/" id="o0" c:root="1">
<UserName i:type="d:string">STERILIZED_OUT</UserName>
<Password i:type="d:string">STERILIZED_OUT</Password>
<ExerciseProgramID i:type="d:string">STERILIZED_OUT</ExerciseProgramID>
<IncomingWorkoutData i:type="d:string">STERILIZED_OUT</IncomingWorkoutData>
<Action i:type="n0:ExchangeEnumerations" xmlns:n0="http://schemas.datacontract.org/2004/07/IronMikeDataExchangeWorkflowService.Enum">GetNextWorkout</Action>
</LiftDataExchange>
</v:Body>
</v:Envelope>
Here is my response dump:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</faultcode>
<faultstring xml:lang="en-US">Object reference not set to an instance of an object.</faultstring>
<detail>
<ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<HelpLink i:nil="true"/>
<InnerException i:nil="true"/>
<Message>Object reference not set to an instance of an object.</Message>
<StackTrace> at System.ServiceModel.Activities.WorkflowOperationContext.HandleEndResumeBookmark(IAsyncResult result)
at System.ServiceModel.Activities.WorkflowOperationContext.OnResumeBookmark()
at System.ServiceModel.Activities.WorkflowOperationContext..ctor(Object[] inputs, OperationContext operationContext, String operationName, Boolean performanceCountersEnabled, Boolean propagateActivity, Transaction currentTransaction, WorkflowServiceInstance workflowInstance, IInvokeReceivedNotification notification, WorkflowOperationBehavior behavior, ServiceEndpoint endpoint, TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Activities.Description.WorkflowOperationBehavior.WorkflowOperationInvoker.OnBeginServiceOperation(WorkflowServiceInstance workflowInstance, OperationContext operationContext, Object[] inputs, Transaction currentTransaction, IInvokeReceivedNotification notification, TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Activities.Dispatcher.ControlOperationInvoker.ControlOperationAsyncResult.PerformOperation()
at System.ServiceModel.Activities.Dispatcher.ControlOperationInvoker.ControlOperationAsyncResult.HandleEndGetInstance(IAsyncResult result)
at System.ServiceModel.Activities.Dispatcher.ControlOperationInvoker.ControlOperationAsyncResult.Process()
at System.ServiceModel.Activities.Dispatcher.ControlOperationInvoker.ControlOperationAsyncResult..ctor(ControlOperationInvoker invoker, Object[] inputs, IInvokeReceivedNotification notification, TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Activities.Dispatcher.ControlOperationInvoker.InvokeBegin(Object instance, Object[] inputs, IInvokeReceivedNotification notification, AsyncCallback callback, Object state)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace><Type>System.NullReferenceException</Type></ExceptionDetail></detail></s:Fault></s:Body></s:Envelope>
UPDATE:
Switching to Edwin's method calls had the same result. So I upgraded from KSoap2 2.6.5 3.0.0-RC4 and now I am getting a NullRefException. With the prior version I would hit the service and throw the object not set error. With this version I do not hit the service and throw NullRef. The code is the same the only thing that changes is which version of KSoap I use. I wrote a simple service (remember these are Workflow Services) that takes a string in, changes it, and kicks a string back out.
FWIW here is my code to make the call:
String SOAP_ACTION = "http://tempuri.org/";
String OPERATION_NAME="ChangeName";
final String WSDL_TARGET_NAMESPACE = SOAP_ACTION;
final String SOAP_ADDRESS= "http://www.icyarmtesting.com/ServiceTest/Service1.xamlx";
Exception exception;
String ErrorMsg="";
String TEST_URL="" ;
SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE, OPERATION_NAME);
//PropertyInfo piName = new PropertyInfo();
//piName.setName("UserName");
//piName.setValue("ramjet");
//piName.setType(String.class);
//request.addProperty(piName);
request.addProperty("UserName", "ramjet");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
envelope.dotNet= true;
envelope.setOutputSoapObject(request);
HttpTransportSE httpTransport =null;
if(!TEST_URL.equals(""))
httpTransport = new HttpTransportSE(TEST_URL);
else
httpTransport = new HttpTransportSE(SOAP_ADDRESS);
Object Response =null;
try
{
httpTransport.call(SOAP_ACTION + "IService/" + OPERATION_NAME, envelope);
Response = envelope.getResponse();
}
catch (SocketTimeoutException ex)
{
ErrorMsg="Unable to connect";
Response=null;
exception=ex;
}
catch (IOException ie)
{
ErrorMsg="Unable to connect";
Response=null;
exception=ie;
}
catch (Exception e)
{
ErrorMsg="Unable to connect";
Response=null;
exception=e;
}
Change the following:
SoapObject response = (SoapObject)envelope.getResponse();
X = response.getProperty(0).toString();
to be:
SoapObject response = (SoapObject)envelope.bodyIn;
if(response != null)
{
X=response.getProperty(0).toString();
}
This was the class that i am using for calling web service hope this might help you
public class CallSOAP {
private String SOAP_ACTION="your action url";
private String OPERATION_NAME="";//The web method OR web service you are going to call
private final String WSDL_TARGET_NAMESPACE=SOAP_ACTION;
private final String SOAP_ADDRESS=Configuration.WEB_SERVICE_URL;//ip-address of serever where you host your service
private Exception exception;
private String ErrorMsg="";
private String TERST_URL="" ;
public Object call(String MethodeName,ArrayList<PropertyInfo> Parameters){
this.OPERATION_NAME=MethodeName;
SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE, OPERATION_NAME);
if(Parameters != null && Parameters.size()>0){
for(PropertyInfo propertyInfo : Parameters){
request.addProperty(propertyInfo);
}
}
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet= true;
envelope.setOutputSoapObject(request);
HttpTransportSE httpTransport =null;
if(!this.TERST_URL.equals(""))
httpTransport = new HttpTransportSE(this.TERST_URL);
else
httpTransport = new HttpTransportSE(SOAP_ADDRESS);
Object Response =null;
try{
httpTransport.call(SOAP_ACTION+OPERATION_NAME, envelope);
Response=envelope.getResponse();
}
catch (SocketTimeoutException ex) {
this.ErrorMsg="Unable to connect";
Response=null;
this.exception=ex;
}
catch (IOException ie) {
this.ErrorMsg="Unable to connect";
Response=null;
this.exception=ie;
}
catch (Exception e) {
this.ErrorMsg="Unable to connect";
Response=null;
this.exception=e;
}
return Response;
}
}
I know its too late to answer this but I faced the same problem and the problem in my code was that I typed the property.setname() incorrect .. make sure you wrote the correct name of the method parameter (copy past it from the wsdl) I'm using ksoap2 3.1.1 btw!
I am using below function in my class to work with SOAP Web-Service.
public static String DeleteGame(String GameIDValue, String PlayerIdValue) {
String responce = null;
SoapObject request = new SoapObject(SOAP_NAMESPACE, SOAP_METHOD_DeleteGame);
PropertyInfo GameId = new PropertyInfo();
PropertyInfo PlayerId = new PropertyInfo();
GameId.setName("gameid");
GameId.setValue(GameIDValue);
PlayerId.setName("PlayerID");
PlayerId.setValue(PlayerIdValue);
request.addProperty(GameId);
request.addProperty(PlayerId);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE aht = new HttpTransportSE(SOAP_URL);
try {
aht.call(SOAP_ACTION_DeleteGame, envelope);
SoapPrimitive LoginResult;
LoginResult = (SoapPrimitive)envelope.getResponse();
System.out.println("=================Delete Game Results: "+LoginResult.toString());
//System.out.println(LoginResult.toString());
responce = LoginResult.toString();
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
return responce;
}
I want to call web service running in Microsoft Dynamics nav ERP i am using ksoap2 library but problem is every time i run my application it throws
java.net.ConnectException: localhost/127.0.0.1:7047 - Connection refused
Microsoft Dynamics nav is using NTLM authentication may that is the problem, please give any suggestion to solve it.
Thanks in advance.
My code is
String namespace = "urn:microsoft-dynamics-schemas/codeunit/NavisionWS";
String url = "http://localhost:7047/DynamicsNAV/WS/Codeunit/NavisionWS";
String soap_action = "urn:microsoft-dynamics-schemas/codeunit/NavisionWS:GetLoginInfo";
String method_name = "GetLoginInfo";
try
{
SoapObject request = new SoapObject(namespace, method_name);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE transport = new HttpTransportSE(url);
transport.call(soap_action, envelope); // Receive Error here!
SoapObject result = (SoapObject) envelope.getResponse();
great = result.toString();
}
catch (Exception e)
{
e.printStackTrace();
great = e.toString();
Toast.makeText(this, great, Toast.LENGTH_LONG).show();
}
Use IP Address instead of Localhost to connect to webservice from Android
Have you added <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> to your manifest?
My .net webservice is apparently running soap 1.2 (by checking the .wsdl) and ive been trying to access the helloworld webservice for testing but i have encountered errors.
Im trying to do this via the emulator by the way.
So when I use soap 1.2 version , i get the error that it is "unable to handle request without a valid action parameter. Please supply a valid soap"
I want to know what I am missing and what should I do.
Thank you!
Things I have already done:
Add permission for android to use the internet
Change from Soap version 1.1 and 1.2
Change from SoapObject to Object (for both soap 1.1 and 1.2)
Used 10.0.2.2 for the emulator
Checked for errors in spelling in the addresses and method names
My codes:
private static final String NAMESPACE = "http://localhost/WebService/";
private static final String URL = "http://10.0.2.2:1672/Eventurous/WsEventurousMobile.asmx";
private static final String HelloWorld_SOAP_ACTION = "http://localhost/WebService/HelloWorld";
private static final String METHOD_NAME1 = "HelloWorld";
...
...
public static String GetHelloWorld() {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME1);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER12);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL,60000);
try {
androidHttpTransport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
androidHttpTransport.call(HelloWorld_SOAP_ACTION, envelope);
SoapObject response = (SoapObject)envelope.getResponse();
String result = response.getProperty(0).toString();
return result;
} catch (Exception e) {
return e.toString();
}
}
Error for Soap version 1.2
Code: soap:Sender, Reason: System.Web.Services.Protocols.SoapException: Unable to handle request without a valid action parameter. Please supply a valid soap action.
at System.Web.Services.Protocols.Soap12ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean
Error for Soap version 1.1
SoapFault - faultcode: 'soap:Client' faultstring: 'System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: http://localhost/WebService/HelloWorld.
at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)' faultactor: 'null' detail: org.kxml2.kdom.Node#413c9098
use
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
instead of
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER12);
and remove this line androidHttpTransport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
and instead of SoapObject response = (SoapObject)envelope.getResponse();
use SoapObject response = (SoapObject)envelope.bodyIn;
It will Help you.If still get Error then Write me.
i am new to android/eclipse(java),in fact this forum too.
Has any one met this situation?
Get input from the user and display the appropriate result by consuming web service from android/eclipse.is there any examples available?
Thank you very much.
I am posting Link of tutorial
Here basic android tutorial to access web service in android basic ksoap android tutorial
and for creating webservice in java use this Tutorial How to create java based web service
Write a web service using java and Then by using ksoap library you will get response. Then Format that response according to your requirement. code for reference:
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL ="http://localhost/Web_Service.asmx?";// replace it by your Webservice URL
private static final String METHOD_NAME = "Function_Name";
private static final String SOAP_ACTION = "Soap Action";
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;
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 response;
response= (SoapObject) envelope.bodyIn;
there are too may example for same Please Google ..................
this is only for initiation
Soap
http://android.vexedlogic.com/2011/04/17/android-lists-iv-accessing-and-consuming-a-soap-web-service-i/
http://seesharpgears.blogspot.in/2010/11/basic-ksoap-android-tutorial.html
Other
http://webhole.net/2011/11/15/android-tutorial-how-to-post-data-from-an-android-app-to-a-website/
http://apachejava.blogspot.in/2011/06/partial-http-post-show-data-webview.html
http://senior.ceng.metu.edu.tr/2009/praeda/2009/01/11/a-simple-restful-client-at-android/