I use ksoap to connect to a soap web service. And get a Soapobject in return. How would I parse this complex soapobject.
My problem is that a SoapObject returns an object for getProperty, this can be a leaf or a node in the tree. I have a complex resultobject that consists of some ints and strings and a list of complex objects. I now somehow have to decide if the property is a leaf or another complex object that can be parsed as an SoapObject.
Is there an example on how to parse this?
You could find this tutorial useful on handling complex objects in KSOAP with Android:
Complex objects tutorial with sample code
Hope this helps
I think, you can use this android web service client open source tool.
Where you needn't parse the complex response object. Its just like call a method of a service.
say, for a service say ComplexRespService with param ComplexResponse you have to just write :
ComplexRespService service = new ComplexRespService ();
CoplextRespPort port = service.getPort();
ComplexResponse resp = port.getResponse ( "someRequest");
In this way, It support the complex request/response. This tool can generate "ws client stub" from just the wsdl file.
I have added a bit about parsing a complex pojo array on the wiki now. Check it out at
http://code.google.com/p/ksoap2-android/wiki/CodingTipsAndTricks
Related
I am trying to parse the results of an API call which returns a unique first property.
{
"AlwaysDifferent12345": {
"fixedname1" : "ABC1",
"fixedname2" : "ABC2"
}
}
I am using retrofit2 and jackson/gson and cannot figure out how to cope with dynamic property names within the retrofit2 framework. The following works fine
data class AlwaysDifferentDTO(
#JsonProperty("AlwaysDifferent12345") val alwaysDifferentEntry: AlwaysDifferentEntry
)
I have tried
data class AlwaysDifferentDTO(
#JsonProperty
val response: Map<String, AlwaysDifferentEntry>
)
But this returns errors Can not instantiate value of type... The return value from the API is fixed i.e. map<string, object>.
I have read you can write a deserializer but it looks like I need to deserialize the whole object when all I want to do is just ignore the string associated with the response.
I have read
https://discuss.kotlinlang.org/t/set-dynamic-serializedname-annotation-for-gson-data-class/14758
and several other answers. Given unique properties names are quite common it would be nice to understand how people deal with this when using retrofit2
Thanks
Because the JSON doesn't have a 1-to-1 mapping Jackson can't map it automatically using annotations. You are going to need to make your own Deserializer.
In this tutorial you can learn how to create your own custom Deserializer for Jackson. https://www.baeldung.com/jackson-deserialization
In the tutorial you will see the first line under the deserialize function is
JsonNode node = jp.getCodec().readTree(jp);
using this line you can get the JSON node as a whole and once you have it you can call this function
JsonNode AlwaysDifferent12345Node = node.findParent("fixedname1");
Now that you have that node you can retrieve its value like shown in the rest of the tutorial. Once you have all the values you can return a new instance of the AlwaysDifferentDTO data class.
Previously I was receiving the response like this:
I was parsing it like: Call<List<MyObject>> getList();
But now there are some new elements were added and the response changed to:
How to parse this object now? I searched my could not find any solutions.
This is how I am setting up my client.
This is the json object which i recieve as a response:
{"map":{"01":{"F":".","E":".","D":null,"C":null,"B":".","A":"."},"02":{"F":".","E":".","D":null,"C":null,"B":"Z","A":"."},"03":{"F":"A","E":"A","D":null,"C":null,"B":"A","A":"A"},"board":false,"type":{"num":"TT334","board":"WW","date":"31MAR","route":"AWETSW","pcount":""}}}
I dont
There are two potential solutions:
You create a DTO. Gson will ignore fields you don't map in your dto. Your json doesn't use a list it is entirely objects.
You manually parse the json using Gson's JsonReader
You can use a mixture of DTOs and manual parsing. I have done this for large json datasets and inconsistent datasets.
I am new to GSON, JSON & hence asking the question:
At the android end, I have to send a booking information to the REST WS on the server. So here is the question:
I have a BookingDTO & I use GSON to serialize it. I send it the REST WS on the server. Now do I also need the same BookingDTO at the server end for GSON deserialize it? (But that would mean tight coupling right?) Do I have to use GSON or can I use normal JSON?
What should be my approach?
You can use Json and parse that content into your objects or directly deal with JsonObject and JsonArray in your methods (server side).
if you want to use objects like BookingDTO you can either re create the classes on android project or reuse those classes from your server side, (or vice versa).
by creating a JAR file that only contains those classes (ex, export model package only) where all POJO classes are located.
using a JAR file makes you maintain a consistency between server and client code, when you add/delete a field, you don't have to change 2 classes, just change in one place and re export the JAR.
now to the tight coupling issue, i don't think there is a one here.
because you are using a list of classes (and you need them in 2 or more separate locations/projects...) this is not coupling, this is reusing same code which should be a good practice.
Coupling is -for example- when Class A is a member of Class B, but it's not when you use Class A and Class B in 2 different systems/components ...
do I also need the same BookingDTO at the server end for GSON
deserialize it?
Simply put, yes, you'll have to prepare a POJO in order to receive the request. So, for that to happen, JSON deserializer will try to parse the properties off JSON request and map that to a POJO of server.
With Spring, we do stuffs like the following. This is a creating a controller of POST request type expecting to habe a param of BookingDTO type. We use Jackson library for JSON serialize and deserialize.
#RequestMapping(value = {"/update"}, method = RequestMethod.POST)
#ResponseBody
public void update(#RequestBody BookingDTO bookingDTO) throws FamsException {
// Do what you intend to do with this bookingDTO object sent from client side(Android)
}
As it stands, if your JSON property name matches with the property name and type of BookingDTO then it can map those and you'll get BookingDTO bookingDTO object with all the matched properties.
Be sure not to send JSON request with property that isn't in the BookingDTO POJO. Otherwise, server will throw a 400 BAD REQUEST error.
Note that, you can also send Map as parameter. This won't require a matching POJO at server side. You can construct a different object by getting the data out of Map the way you like.
Hope you get the idea.
I have a Json of this type :
{
"4f958ef28ecd651095af6ab6": {
enormous JsonObject
}
}
the "4f958ef28ecd651095af6ab6" is different each time (but I know what it will be as it is a parameter of my api call), it corresponds to the id of the following object. I have a Gson-configured model to parse the enormous JsonObject.
My question is : is it performant to use simply
new JSONObject(jsonresponse).getJSONObject("4f958ef28ecd651095af6ab6")
and parse with Gson from there ?
Is there a better way to do so ?
I guess the real question would be, what does "new JSONObject(String)" realy do ?
Thanks
What you are doing is:
You load all the Json string into the phone memory (memory issue + long time to load entirely)
You create a big JSONObject (same issues) in order to have access to each key.
You write few code but this is not the most performant solution.
To minimized the memory impact and accelerate the operation of objects' creation, you can use Gson in stream mode.
By directly read the input stream, you avoid to load too much data and you can directly start to populate your object piece by piece.
And about the JSONObject, it will mostly check if your json string is correct (or it will throw a JsonException) and it will let you look into the object when you search for a key and its value.
I would recommend use hybrid (native and gson) since i am not sure how to get unknown jsonobject with GSON.
You need to get your response as a JSONArray, then itarete for each JSONObject. You can experiment parsing code as trying. Please check JSONArray.getJSONObject(int index) method. Then we can use GSON to get our data model to get known attributes.
If you can post complete json data, we can give it chance to parse together.
I've been searching for the past week on how to develop an android project, read some on android developers page and on other websites like here, but no text was complete.
i have this project - i'm a php developer not a java, but could understand a bit about java lately.
the thing is i want to develop an android app using my website, i did output a json type data from my website, and gonna use them on the android app, i did the async request on android and could read the data form the website but :
first question: how to parse the json data correctly and convert it to array on android, i did that through:
Iterator<String> itr = myObject.keys();
while (itr.hasNext()) {
...
i don't know if that's the correct way, when i try to convert my json object to array, it gives me type mismatch.
second and more importantly:
how can create a "Block" like facebook posts style, or twitter style blocks, you know - blocks of json data, is it a linearlayout ? what do i call it ? and how can i add it to the UI dynamically, cuz these blocks are pulled from the website json data. so they are arrays...of blocks..
i'm kinda confused still, i need a start point.
Thank you!
excellent tutorial for beginners for android development
http://thenewboston.org/list.php?cat=6
and for your first question - how to parse json data correctly,
you can try using gson to convert the json data into POJO
otherwise you'd have to do myObject.opt(key) to make sure it is there
First question: you should use a library to parse JSON, it's simpler that way. Try gson. You should create a class, which holds the parsed object, like:
public class Taxi implements Serializable {
private static final long serialVersionUID = 1L;
#SerializedName("idTaxi")
private Integer idTaxi;
#SerializedName("name")
private String name;
//getter, setters, constructor, etc
}
Then when you get the JSON object, you can parse it:
Gson gson = new Gson();
Reader reader = new InputStreamReader(SOURCE_STREAM);
Taxi[] response = gson.fromJson(reader, Taxi[].class);
Second question: i think a ListView would be good for you. You can read a full tutorial about it here