I am attempting to use kSOAP 2 in my android application, and when I try to perform a particular webservice request, I end up getting thrown a "double ID" exception. I was able to find where this gets thrown in the kSOAP source code, it is in the SoapSerializationEnvelope class method public Object read() Here is an excerpt from that code showing the exception being thrown:
if (id != null) {
Object hlp = idMap.get(id);
if (hlp instanceof FwdRef) {
FwdRef f = (FwdRef) hlp;
do {
if (f.obj instanceof KvmSerializable)
((KvmSerializable) f.obj).setProperty(f.index, obj);
else
((Vector) f.obj).setElementAt(obj, f.index);
f = f.next;
} while (f != null);
} else if (hlp != null)
throw new RuntimeException("double ID");
idMap.put(id, obj);
}
I'm not at all sure what this exception is about, or how I can fix it. Anyone know what the deal with this exception is?
Thanks
Edit:
It should be noted that I am also using a SOAP webservice connection method in the iOS version of this application, and the same exact request does not have any problems.
New information:
Upon closer inspection, the problem seems to be resulting from the xml response I am getting containing a <diffgr:before> element, which has tables with the same ID as above. I think this is the cause of the problem, the other requests I have performed up to this point do not have that element in them, and do not have the exception. So to add to the question: can I stop the webservice from sending this block in its response, or get kSOAP to ignore it?
I was able to resolve this by removing the diffgr:before element the webservice was sending. I did that thanks to this post
well, I had the same problem too, but I had no diffgr:before in the xml response (And I can't change the webservice at all). Anyway, the problem was due to some empty values in the response. Using XOM
I managed to remove all empty elements and the it worked like charm. This is done by converting the response to string, loading it into nu.xom.Document element, remove the empty elements from the document and revert it back to InputStream for parsing with ksoap2
Related
I've overrided method delete in my Yii2 controller, but i can not call it from Android application with library Retrofit.
public function actionDelete($id)
{
$model=$this->findModel($id);
if($model->delete())
{
$this->setHeader(200);
echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
}
else
{
$this->setHeader(400);
echo json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT);
}
}
I tried 2 versions of calling:
first
#DELETE("posts/delete/{id}")
second
#DELETE("posts/{id}")
Call<Void> deletePosts(#Path("id") int id);
But I get error 404. So how should I correctly call this method?
When I try to call not overrided method I get error 500.
Maybe somebody knows how can I call delete method from Android to Yii2 rest?
Thanks in advance.
To pass a parameter as in public function actionDelete($id), you need to call /posts/delete?id=<id>, not just /posts/delete/<id>. However, getting this wrong should result in a HTTP 400 Bad Request error, not in a 404 Not Found error.
Possible reason for the 404 error: I assume $model=$this->findModel($id); is generated code. If so, it's likely throwing a NotFoundHttpException exception if a model with the given ID could not be found.
Another thing you can check is if a VerbFilter is configured in the behaviors() method of your controller to only allow POST requests for the delete action. You might be sending a GET request.
Using Retrofit 2.3.0 I am getting the following message in Android Studio
Any suggestions on how I could remove this IDE error message. Thanks
From the Response documentation:
#Nullable
public T body()
The deserialized response body of a successful response.
This means that response.body() can return null, and as a result, invoking response.body().getItems() can throw a NullPointerException. To avoid the warning message, check that response.body() != null before invoking methods on it.
Edit
Discussion on another question revealed that my statements above are not as clear as they need to be. If the original code was:
mAdapter.addItems(response.body().getItems());
It will not be solved by wrapping in a null check like this:
if (response.body() != null) {
mAdapter.addItems(response.body().getItems());
}
The linter (the thing generating the warning) has no way of knowing that each response.body() invocation is going to return the same value, so the second one will still be flagged. Use a local variable to solve this:
MyClass body = response.body();
if (body != null) {
mAdapter.addItems(body.getItems());
}
I am trying something very simple. I have a custom API called "missingvehiclesfrominventoryjob" and it simply returns a record set from an standard SQL Query.
I can do this in my WinForms and Windows Phone app easily but I cannot figure out how to do this on the Android App.
Here is my code: (which DOES NOT COMPILE in Android Studio):
msClient.invokeApi("missingvehiclesfrominventoryjob", kd, new
ApiOperationCallback<List<InventoryProspects>>(){
#Override
public void onCompleted(List<InventoryProspects> missingVehicles, Exception e,
ServiceFilterResponse serviceFilterResponse){
for (InventoryProspects item : missingVehicles){
mAdapter.add(item);
}
}
});
The problem is the List in the parameters of the Callback. I am not sure how to indicate that the invoiceAPI call will return multiple rows from the database and I cannot find anywhere in the docs to explain how. Nor can I find an example ANYWHERE on the internet.
I am sure I am not the only on trying to do this.
Thanks in advance
Chuck Giddens
What i did to overcome this problem, is to call a different overload of invokeApi that returns a JsonElement, and then deserialise it into my objects like so:
mClient.invokeApi("MyCustomApi",null, "GET", null, new ApiJsonOperationCallback() {
#Override
public void onCompleted(JsonElement jsonElement, Exception e, ServiceFilterResponse serviceFilterResponse) {
GsonBuilder gsonb = new GsonBuilder();
Gson gson = gsonb.create();
JsonArray array = jsonElement.getAsJsonArray();
List<MyObject> myObjects = new ArrayList<MyObject>()>
for(int i = 0; i < array.size(); i++)
{
myObjects.add(gson.fromJson(array.get(i).getAsJsonObject().toString(), MyObject.class));
}
}
});
I haven't had a chance to test it yet (will try when I have time and edit answer as needed) but my thinking is that the Android SDK won't allow you to do what you're trying to do. The invokeApi methods expect a strongly typed class to be set as the response type (or you can use the raw JSON methods). In this case, you're trying to say you want a list of items back, but I don't think that will work. I think you'll instead need to create a new class (i.e. missingvehiclesfrominventoryjobResponse) which contains a property that is of type List< InventoryProspects>. Note that you'll need to change your method call to actually match one of the available options for invokeApi which I don't believe it's doing right now. You can read more about the different formats of the method here: http://blogs.msdn.com/b/carlosfigueira/archive/2013/06/19/custom-api-in-azure-mobile-services-client-sdks.aspx
Alternatively, you can use the table methods against a table endpoint where the read expects a collection of results back.
Have you tried to remote debug your API call from the app.[http://blogs.msdn.com/b/azuremobile/archive/2014/03/14/debugging-net-backend-in-visual-studio.aspx]. Your app will timed out in doing that but you can see line by line execution of your controller action if it returns the correct result set. If there is no problem with it then the problem should be in parsing result set.
What is the exception you are getting in callback? And have you tried using other method parameters such as passing with different HTTP methods? Use this as a reference as well. http://azure.microsoft.com/en-us/documentation/articles/mobile-services-android-get-started/
Please paste your exception or either controller action, and the object structure of the data transfer object of the result set.
#Get("/ServiceTest?version=1&dateRange={dateRange}")
ResponseModel getDateRangeTest(String dateRange);
in RestClient interface this make the following Get
http://localhost:8080/ServiceTest/2014-01-29%25202014-01-29?version=1" resulted in 400 (Bad Request); invoking error handler
Am i doing something wrong in sending the query params.
I want address this way:
/ServiceTest?version=1&dataRange=2014-01-29%25202014-01-29
Which in this case somehow i am failed to generate with Android annotations #Get
Answer: My calls were not correct and main problem was with uri encode, correct one is
/ServiceTest?version=1&dataRange=2014-01-29%202014-01-29
you might do wrong.
Your server get /ServiceTest
but you access server with address /ServiceTest/2014-01-29%25202014-01-29
Look careful that your server receive as /ServiceTest?version=1&dateRange={dateRange}
and {dataRange} is what you intend to give as variable.
Your address should be /ServiceTest?version=1&dataRange=2014-01-29%25202014-01-29
== EDIT ==
I'm not familiar with Android Get annotation, but try this.
#Get("/ServiceTest?version=1&dateStart={dateStart}&dateEnd={dateEnd}")
ResponseModel getDateRangeTest(String dateStart, String dateEnd);
and access with /ServiceTest?version=1&dataStart=2014-01-29&dateEnd=2014-01-29
Note that I change argument for more specific. and it would be a better approach.
I am struggling with an issue that I can't seem to make sense of.
I have downloaded my json feed which I am storing as text. I am creating a new instance of my JsonDataReader class which parses my jsonfeed into class properties.
When I debug- I can see that the class properties are correctly being created however when my main activity resumes the object doesn't seem to have any properties ie it( has gone back to null)
Is there an issue with the way I am calling it?
DKEntryJsonDataReader dkjsdr = null;
try {
dkjsdr = new DKEntryJsonDataReader(result);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setContentView(R.layout.dk_entry_parentview);
//grab the views
TextView title=(TextView) findViewById(R.id.tv_dk_titlelisting);
TextView body=(TextView) findViewById(R.id.tv_dk_bodylisting);
title.setText(dkjsdr.titletext); //returns as null!
body.setText(dkjsdr.pText); //returns as null!
Edit:
Ok - looks like I have just worked it out. The reason that the object was coming up as null was that the Json didn't have all the required fields in so was erroring out before completing the constructing class. So might be worth putting a validity checker in prior to parsing.
Discovered this by using the wonders of debugging the error code. (e)
am adding Log.e!
Ok - looks like I have just worked it out. The reason that the object was coming up as null was that the Json didn't have all the required fields in so was erroring out before completing the constructing class. So might be worth putting a validity checker in prior to parsing.
Discovered this by using the wonders of debugging the error code. (e) am adding Log.e!