How to send DateTime to .net webService from android (ksoap2)? - android

I've a .net webservice, where I have to send a param (type of dateTime), as You can see:
<startDateTime>dateTime</startDateTime>
In Android client, I use ksoap2, and I don't know , How to send that type of data?
Please help with setting this type - code below not works.
PropertyInfo propInfo3 = new PropertyInfo();
propInfo3.name="startDateTime";
propInfo3.value="2012-02-01";

Here is how I call web service methods in my application. Note the method I used to convert java dates. You require an ISO date format.
protected static Object callMethod(String method, Map<String, Object> parameters) throws IOException, XmlPullParserException {
SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE, method);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.headerOut = new Element[1];
envelope.headerOut[0] = buildAuthHeader();
envelope.setOutputSoapObject(request);
if (parameters != null) {
for (String item : parameters.keySet()) {
Object itemValue = parameters.get(item);
if (itemValue.getClass().getName().equals("java.util.Date")) {
// If it's a date then we have to format it because ksoap
// does not know how to do this.
request.addProperty(item, getSOAPDateString((java.util.Date) itemValue));
} else {
request.addProperty(item, itemValue);
}
}
}
HttpTransportSE httpTransport = new HttpTransportSE(SOAP_ADDRESS, 10000);
httpTransport.debug = true;
httpTransport.call(WSDL_TARGET_NAMESPACE + "/" + method, envelope);
String soapString = httpTransport.requestDump;
System.out.println(soapString);
return envelope.getResponse();
}
Here is the method that returns the actual string:
private static Object getSOAPDateString(java.util.Date itemValue) {
String lFormatTemplate = "yyyy-MM-dd'T'hh:mm:ss'Z'";
DateFormat lDateFormat = new SimpleDateFormat(lFormatTemplate);
String lDate = lDateFormat.format(itemValue);
return lDate;
}

In your server, what's the return from the client?
When I have a problem like this, I show in the Logcat on Android what I'm sending and in the server side what I'm getting.
I had a little problem with date too (I'm using ksoap2 and webservices), I solve my problem sending the date in the util.Date, then I use SimpleDateFormat with a pattern date in my project and convert that string to what I want.
cya,
Bertan
Here is my code that sends to the WS:
public static byte[] send(String... param) throws SocketTimeoutException, IOException, XmlPullParserException, Exception{
//First I send the WS Name
String ws = param[0];
//Second is the operationName
SoapObject soap = new SoapObject(URL_SOAP, param[1]);
Object retorno = null;
int tamParam = param.length;
//The 3 parameter for the infinity its the properties, name and the next it's the value...
if (tamParam > 0) {
for (int i = 2; i < tamParam; i++) {
soap.addProperty(param[i], param[++i]);
}
}
// create a envelope for the soap object
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(soap);
// create a HttpTransport to send the object soap with 15s delay
MyHttpTransport httpTransport = new MyHttpTransport(URL + ws, 15000);
// send the req
Long tempo1 = 0l;
tempo1 = System.currentTimeMillis();
httpTransport.call("", envelope);
retorno = envelope.getResponse();
Long tempo2 = System.currentTimeMillis();
httpTransport.reset();
//I ever get byte[] from the WS...
if (retorno != null) {
byte[] bloc = Base64.decode(retorno.toString(), Base64.DEFAULT);
return bloc;
} else {
return null;
}
}

Related

Android ksoap2 WCF wsHttpBinding

I am trying to connect my android application to WCF web service (IIS 6),with
basicHttpBinding everything works OK, but i want it to be more secure so i set the
WCF binding to wsHttpBinding, i understed this is a littele bit tricky on ksoap2,
i am getting an error:
Code: s:Sender, Reason: The message could not be processed.
This is most likely because the action 'http://tempuri.org/IService1/HelloWorld'
is incorrect or because the message contains an invalid or expired security context token or
because there is a mismatch between bindings.
The security context token would be invalid if the service aborted the channel due to inactivity.
To prevent the service from aborting idle sessions prematurely increase the Receive timeout
on the service endpoint's binding.
Here is my code (android)
Element e = new Element();
e.setName("To");
e.setNamespace("http://www.w3.org/2005/08/addressing");
e.addChild(Node.TEXT,
URL);
Element e1 = new Element();
e1.setName("Action");
e1.setNamespace("http://www.w3.org/2005/08/addressing");
e1.addChild(Node.TEXT,
"http://tempuri.org/IService1/HelloWorld");
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER12);
SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
//envelope.implicitTypes = true;
envelope.dotNet = true;
//envelope.headerOut =new Element[] { e, e1 };
envelope.headerOut = buildHeader(URL, SOAP_ACTION);
envelope.setOutputSoapObject(Request); // prepare request
try {
// androidHttpTransport.call(SOAP_ACTION, envelope);
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapObject result=(SoapObject)envelope.getResponse();
String resultData=result.getProperty(0).toString();
//Object result = envelope.getResponse();
//SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
//String resultData = result.toString();
//msg = resultData;
} catch (IOException | XmlPullParserException ex) {
ex.printStackTrace();
msg = ex.getMessage();
}
i all so try:
private static Element[] buildHeader(String url, String soapAction) {
String HTTP_ADDRESSING_ANONYMOUS = "http://www.w3.org/2005/08/addressing/anonymous";
String HTTP_ADDRESSING = "http://www.w3.org/2005/08/addressing";
String ACTION = "Action";
String TO = "To";
String ADDRESS = "Address";
String REPLY_TO = "ReplyTo";
String MUST_UNDERSTAND = "mustUnderstand";
List<Element> headers = new ArrayList<Element>();
Element elementAction = new Element().createElement(HTTP_ADDRESSING, ACTION);
elementAction.addChild(Node.TEXT, soapAction);
elementAction.setAttribute(HTTP_ADDRESSING, MUST_UNDERSTAND, "1");
headers.add(elementAction);
Element elementTo = new Element().createElement(HTTP_ADDRESSING, TO);
elementTo.addChild(Node.TEXT, url);////////////////////////////
elementTo.setAttribute(HTTP_ADDRESSING, MUST_UNDERSTAND, "1");
headers.add(elementTo);
Element elementReplyto = new Element().createElement(HTTP_ADDRESSING, REPLY_TO);
Element address = new Element().createElement(HTTP_ADDRESSING, ADDRESS);
elementReplyto.addChild(Node.ELEMENT, address);
address.addChild(Node.TEXT, HTTP_ADDRESSING_ANONYMOUS);
elementReplyto.setAttribute(HTTP_ADDRESSING, MUST_UNDERSTAND, "1");
headers.add(elementReplyto);
int size = headers.size();
Element[] array = new Element[size];
for (int i = 0; i < size; i++) {
array[i] = headers.get(i);
}
return array;
}
can someone Help

org.xmlpull.v1.xmlpullparserexception expected start_tag error when using ksoap2

I use ksoap2 to connect .NET by web service.
This is my Dataset
public DataSet getphimall()
{
DataSet ds1 = new DataSet();
try
{
SqlConnection cnn = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=EMHAUI;Integrated Security=True");
SqlCommand cmd = new SqlCommand("sp_GetAllSemester_ad", cnn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds1);
return ds1;
}
catch (Exception e)
{
return null;
}
}
And this is my webservice
[WebMethod]
public DataSet getSM()
{
Class1 phim1 = new Class1();
return phim1.getphimall();
}
And this is my javaconnector class
public class getSM {
String tenphim;
String daodien;
private static final String SOAP_ACTION = "http://tempuri.org/getSM";
private static final String METHOD_NAME = "getSM";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://10.0.2.2:50532/wsAndroid.asmx";
public getSM getallphim()
{
SoapObject table = null;
SoapObject client = null;
SoapObject tableRow = null;
SoapObject responseBody = null;
AndroidHttpTransport transport = null;
SoapSerializationEnvelope sse = null;
//cái này trong tut viết thế, mình lười đổi tên
sse = new SoapSerializationEnvelope(SoapEnvelope.VER11);
sse.addMapping(NAMESPACE, "getSM", this.getClass());
sse.dotNet = true;
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
getSM setphim = new getSM();
try
{
client = new SoapObject(NAMESPACE, METHOD_NAME);
sse.setOutputSoapObject(client);
sse.bodyOut = client;
androidHttpTransport.call(SOAP_ACTION, sse);
responseBody = (SoapObject) sse.getResponse();
responseBody = (SoapObject) responseBody.getProperty(1);
table = (SoapObject) responseBody.getProperty(0);
tableRow = (SoapObject) table.getProperty(0);
setphim.daodien = tableRow.getProperty("ID").toString();
setphim.tenphim = tableRow.getProperty("SemesterName").toString();
return setphim;
} catch (Exception e)
{
setphim.daodien = e.toString();
setphim.tenphim = e.toString();
return setphim;
}
}}
But When I run my emulator, I have an error
org.xmlpull.v1.xmlpullparserexception expected start_tag error
Please help me! Thanks
There might be a few reasons for the exception that you are getting.
Wrong Parameters for the SOAP call : try to confirm if the values of NAMESPACE, ACTION, METHOD and URL are correct or not, by looking at the WSDL file
Invalid response from server : try to log the response that the server sends to you and check if you are getting correct well-structured XML or not
androidHttpTransport.debug = true;
//execute request
androidHttpTransport.responseDump; //response string from server
dotNet attribute of the envelope : try using soapEnvelope.dotNet=true

Ksoap2 Android adding Attributes to a simple property

I am trying to create a new property inside a SoapObject that will contain simple string properties with attributes to them like this:
<Power Unit="kw">1500</Power>
here is the code i am using for my samples below.
final SoapObject powerObject= new SoapObject(namespace, "Power");
powerObject.addAttribute("Unit", getPowerUnit());
PropertyInfo powerObjectProperty = new PropertyInfo();
powerObjectProperty .setName("");
powerObjectProperty .type = String.class;
powerObjectProperty .setValue(getPower());
powerObjectProperty .addProperty(powerObjectProperty);
root.addSoapObject(powerObject); // this is my root for the hierarchy
The best that i could reach is the following:
<Power Unit="kw"><>1500</></Power>
i even tried to add everything as a string but that encodes the <> tags.
&ltPower Unit"kw"&gt1500&lt/Power&gt
I am using:
ksoap2-android-assembly-2.6.0-jar-with-dependencies.jar on android.
Ok i have solved this issue, here is how:
I have created a new soap object called TextSoapObject
public class TextSoapObject extends SoapObject {
public static final String TAG = TextSoapObject.class.getSimpleName();
public TextSoapObject(String namespace, String name) {
super(namespace, name);
}
public String text;
public void setText(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
Next i overrided SoapSerialization envelope like this:
public class ValueSerializationEnvelope extends SoapSerializationEnvelope {
public ValueSerializationEnvelope(int version) {
super(version);
}
public static final String TAG = ValueSerializationEnvelope.class.getSimpleName();
#Override
public void writeObjectBody(XmlSerializer writer, KvmSerializable obj) throws IOException {
if (obj instanceof TextSoapObject) {
writer.text(((TextSoapObject) obj).getText());
}
super.writeObjectBody(writer, obj);
}
}
And that's it.
To use this you would do the following:
final TextSoapObject costOfRepairs = new TextSoapObject(namespace, "CostOfRepairs");
costOfRepairs.addAttribute("Currency", getCurrency());
costOfRepairs.setText(getRepairCosts() + "");
root.addSoapObject(costOfRepairs);
EDIT:
This issue has been recognized for the ksoap2 library and addressed here:
http://code.google.com/p/ksoap2-android/issues/detail?id=112
Should be fixed in the next ksoap2 Release.
Try the following code
SoapObject soOriginDestInfo = new SoapObject(namespace_ns, "OriginDestinationInformation");
SoapPrimitive spDeptDtTm = new SoapPrimitive(namespace_ns, "DepartureDateTime", "asdadsad");
spDeptDtTm.addAttribute("Unit", "kw");
soOriginDestInfo.addProperty("DepartureDateTime", spDeptDtTm);
request.addSoapObject(soOriginDestInfo);
You can add property in your soap object and pass any value you want.
SoapObject request = new SoapObject(NAMESPACE, NAME);
request.addProperty("powerInKw", 1500);
like a key value pair.
I'm consuming some .NET web services and need to addAttribute to an addProperty while using ksoap for this xml:
<Element FirstAttribute="int" SecondAttribute="double" />
Here's what I did (including some extra help looping and passing in a double) to pass in this request:
String xml = null;
final String NAMESPACE = "http://yournamespace.org/";
final String SOAP_ACTION = "http://yournamespace.org/NameOfYourOperation";
final String METHOD_NAME = "NameOfYourOperation";
final String URL = "http://whereyourserviceis.com/Service.asmx";
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
for (int i=0; i < anArray.size(); i++)
{
Some_obj obj = anArray.get(i);
SoapObject attributes = new SoapObject(NAMESPACE, "Element");
int a = Integer.parseInt(obj.someIntString);
attributes.addAttribute("FirstAttribute", a);
Double v = Double.parseDouble(obj.someDoubleString);
attributes.addAttribute("Value", v);
request.addProperty("SecondAttribute", attributes);
//request.addSoapObject(request);
Log.d(TAG,"=======obj.someIntString======: " + a + "=======obj.someDoubleString========: " + v);
}
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
MarshalFloat md = new MarshalFloat();
md.register(envelope);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
envelope.implicitTypes = true;
envelope.setAddAdornments(false);
try
{
HttpTransportSE transport = new HttpTransportSE(URL, 60000);
transport.debug = true;
transport.call(SOAP_ACTION, envelope);
xml = transport.responseDump.toString();
Log.d(TAG, "getUpdates===============" + xml);
}
catch(SocketException ex)
{
Log.e("SocketException : " , "Error on getUpdates() " + ex.getMessage());
}
catch (Exception e)
{
Log.e("Exception : " , "Error on getUpdates() " + e.getMessage());
}
Take note of the MarshalFloat part...this is there if you're passing in a double value so the soap can serialize properly.

How to parse a SoapObject in android

I'm using webservices for an application to get the data from external servers. I'm able to connect to the server, send my SOAP request and able get the data back to my android class as SoapObject.
Here I'm having trouble parsing this SoapObject to retrieve the values (as strings) coming from the webservice.
My code is here:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
mInflater = (LayoutInflater)getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
System.out.println("Entered "+getClass().getSimpleName());
//Calling the web service to get the documents list
callService("getDocumentsList","http://wservice.friedmaggy.com/getDocumentsList");
-- I have created callService method to call the webservice.:
public void callService(String operation, String soapaction)
{
try {
String SOAP_ACTION = soapaction;
String OPERATION_NAME = operation;
String WSDL_TARGET_NAMESPACE = getString(R.string.targetNamespace);
String SOAP_ADDRESS = getString(R.string.soapAddress);
SoapObject request = new SoapObject(
WSDL_TARGET_NAMESPACE, OPERATION_NAME);
System.out.println("SOAP_ACTION "+SOAP_ACTION);
System.out.println("OPERATION_NAME "+OPERATION_NAME);
System.out.println("WSDL_TARGET_NAMESPACE "+WSDL_TARGET_NAMESPACE);
System.out.println("SOAP_ADDRESS "+SOAP_ADDRESS);
// System.out.println("SOAP_ACTION "+SOAP_ACTION);
PropertyInfo propInfo = new PropertyInfo();
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
HttpTransportSE httpTransport = new HttpTransportSE(
SOAP_ADDRESS);
envelope.setOutputSoapObject(request);
httpTransport.call(SOAP_ACTION, envelope);
SoapObject response = (SoapObject) envelope.bodyIn;
if(response.getPropertyCount()>0){
data=new StringBuilder();
for (int i = 0; i < response.getPropertyCount(); i++) {
Course c = new Course((SoapObject) response.getProperty(i));
courseList.add(c);
}
for (Course c : courseList) {
data.append("CourseName :" + c.getName());
results.add(c.getName());
}
-- As seen above, i'm passing the whole response object to another bean class to fetch the values.(Course c = new Course((SoapObject) response.getProperty(i));)
Can you help me how to parse this response object to fetch the required String values out.?
androidHttpTransport.call(SOAP_ACTION, envelope);
Object response = envelope.getResponse();
Vector<SoapObject> res= null;
if (response instanceof SoapObject) {
res = new Vector();
res.add((SoapObject) response);
} else if (response instanceof Vector) {
res = (Vector<SoapObject>) response;
}
for(SoapObject so1: res){
//retrieve String here from soap object using this
so1.getProperty(0).toString();
//then so1.getProperty(1).toString and likewise
}

Passing ArrayList of custom object to kSOAP function

This is the function which is to call the function in the server to perform some task. But i have to pass in a ArrayList and a String value. I have trouble passing the ArrayList to the server. Can anyone tell me what i should do?
public void findLocation(ArrayList<APData> apdatalist, String profilename){
SoapObject request = new SoapObject(NAMESPACE, "FindLocation");
PropertyInfo quotesProperty = new PropertyInfo();
quotesProperty.setName("profileName");
quotesProperty.setValue(profilename);
quotesProperty.setType(String.class);
request.addProperty(quotesProperty);
request.addProperty("AP_List", APData.class);
envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE httpRequest = new HttpTransportSE(URL);
httpRequest.debug = true;
String result = "";
try
{
httpRequest.call(SOAP_ACTION, envelope);
Log.e("Request",httpRequest.requestDump.toString());
SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
Log.e("Response",httpRequest.responseDump.toString());
result = response.toString();
if(result == null){
Log.e("AndroidRuntime", "No location result is return!");
}
}
catch(Exception e)
{
e.printStackTrace();
}
//return temp;
}
I've found a possible solution. I've modified the SoapSerializationEnvelope class to deal with ArrayList.
I modified the method
public void writeObjectBody(XmlSerializer writer, KvmSerializable obj)
public void writeObjectBody(XmlSerializer writer, KvmSerializable obj) throws IOException
{
// Added this code for parsing attributes of KvmSerializable objects
int cnt = obj.getPropertyCount();
PropertyInfo info = new PropertyInfo();
for (int i = 0; i < cnt; i++)
{
Object prop = obj.getProperty(i);
if(!(prop instanceof SoapObject)) {
// prop is a PropertyInfo
obj.getPropertyInfo(i, properties, info);
// Added this code to parse ArrayList objects in requests
if(prop instanceof ArrayList<?>){
ArrayList<?> values = (ArrayList<?>)prop;
for(Object o : values){
writer.startTag(info.namespace, info.name);
writeProperty(writer, o, info);
writer.endTag(info.namespace, info.name);
}
}else if ((info.flags & PropertyInfo.TRANSIENT) == 0)
{
writer.startTag(info.namespace, info.name);
writeProperty(writer, obj.getProperty(i), info);
writer.endTag(info.namespace, info.name);
}
} else {
// prop is a SoapObject
SoapObject nestedSoap = (SoapObject)prop;
writer.startTag(nestedSoap.getNamespace(), nestedSoap.getName());
writeObjectBody(writer, nestedSoap);
writer.endTag(nestedSoap.getNamespace(), nestedSoap.getName());
}
}
}
This seems to work for me

Categories

Resources