I need to map a JSON object to a class using GSON, here is the JSON object:
{
"protocols": [
[ "https", 39 ],
[ "http", 1 ]
],
...
}
Generally if there are entity names specified it is easy to do something like this:
{
"protocols": [
[ "name":"https", "count":39 ],
[ "name":"http", "count":1 ]
],
...
}
class ProtocolItem {
#SerializedName("name")
String protocolName;
#SerializedName("count")
int count;
}
However since no entity names are specified in this case, I am not sure how to do the mapping for this. Please point some directions for me if you are familiar with the case.
Thanks
Unlike your first example,
[ "name":"https", "count":39 ],
is invalid JSON as you can either specify an array using [1, 2] without any names or a map using {"x": 1, "y": 2} with "entity names" as keys. So the solution is simple:
{
"protocols": [
[ "https", 39 ],
[ "http", 1 ]
],
}
is a map with a single key and a value which is an array of arrays of objects. You can map it as
class All {
Object[][] protocols;
}
You must use Object here, as it needs to accept both strings and ints. Instead of arrays, you can use Lists.
I guess, you'd prefer to serialize it as
class All {
Map<String, Integer> protocols;
}
This is possible, too, but you need a TypeAdapter. The very first linked example shows clearly how to do it (start with beginArray, in a loop test JsonToken.BEGIN_ARRAY and do nextString and nextInt, etc.).
Related
I have a very large json file within my android app with the following struture:
[
{
"id": 123,
"data": {
...
}
},
{
"id": 456,
"data": {
...
}
},
...
]
Depending on the item selected in the UI, I need to deserialize only the item with the corresponding id, but right now I'm deserializing the whole file and then do the filter, which takes time and memory to just extract the id I need.
Is there a way to deserialize only the section I need?
I'm using kotlinx.serialization.
I have the following contract
"shape": {
"type": "MultiPoly",
"points": [
[
[
[
-92.53941242522892,
41.51492979593705
],
[
-92.53942433363545,
41.51493000420402
],
.
.
.
"shape": {
"type": "Poly",
"points": [
[
[
-92.6814794540405,
41.7796968811509
],
[
-92.6820158958435,
41.7801769167539
]
.
.
.
As you can see, MultiPoly has another level in the array hierarchy. How can I create a POJO to successfully parse both cases? Is it possible?
List<List<List<Double>>> points; seems to work but only for Polys.
Thanks,
Otterman
So I was able to figure this out by storing the points in a generic Object [] array and then parsing manually based on the type.
private Object[] points;
Using the Sheets API in Android, how would I be able to find all the sheets I have in a spreadsheet ? Don't see anything straightforward in the API docs, but maybe there is a clever WA to get those.
to illustrate, in the below example, I would like to get the 5 labels of the 5 worksheets:
[EDIT] Follow-up question (thanks Trevor), showing my (lack of) Java skills:
So this way I can get the title of the first Worksheet:
Spreadsheet responseSpreadSheet = this.mService.spreadsheets().get(sheetsID).execute();
String First_Sheet_Title = responseSpreadSheet.getSheets().get(0).getProperties().getTitle();
Out of curiosity, why doesn't this approach work ? It doesn't let me apply the 'getProperties' method on the single sheet I assume to get back from 'get(0). I'm sure it's some basic Java thing I'm missing:
List responseSheets = responseSpreadSheet.getSheets();
String First_Sheet_Title = responseSheets.get(0).getProperties().getTitle();
Also, is there an easy way to get all worksheet names in a single line ? Right now I plan to iterate over the list/array I get back from getSheets, is there a way to apply the 'getTitle' directly on it to get back the list of worksheet names ? (Hope that question is somewhat meaningful)
In the API docs it shows that when you GET a Spreadsheet the response body will contain an instance of a Spreadsheet.
The Spreadsheet contains an array sheets which are all of the Sheets in the Spreadsheet
{
"spreadsheetId": string,
"properties": {
object(SpreadsheetProperties)
},
"sheets": [
{
object(Sheet)
}
],
"namedRanges": [
{
object(NamedRange)
}
],
"spreadsheetUrl": string,
}
Each Sheet has a SheetProperties object:
{
"properties": {
object(SheetProperties)
},
"data": [
{
object(GridData)
}
],
"merges": [
{
object(GridRange)
}
],
"conditionalFormats": [
{
object(ConditionalFormatRule)
}
],
"filterViews": [
{
object(FilterView)
}
],
"protectedRanges": [
{
object(ProtectedRange)
}
],
"basicFilter": {
object(BasicFilter)
},
"charts": [
{
object(EmbeddedChart)
}
],
"bandedRanges": [
{
object(BandedRange)
}
],
}
The SheetProperties object contains a title field which is the label you're looking for:
{
"sheetId": number,
"title": string,
"index": number,
"sheetType": enum(SheetType),
"gridProperties": {
object(GridProperties)
},
"hidden": boolean,
"tabColor": {
object(Color)
},
"rightToLeft": boolean,
}
I want to post the following JSON object in a POST request over retrofit
{
"Inputs": {
"input1": {
"ColumnNames": [
"Name",
"Weekday",
"Time",
"Type"
],
"Values": [
[
" ",
"1",
"9:00:34",
"OUTGOING"
],
]
}}
How do I represent this as a GSON object? I have only found very easy examples online (like {'Foo':'bar'} sort). Any help is greatly appreciated
Use http://www.jsonschema2pojo.org/ to generate the java classes
{
"Inputs": {
"input1": {
"ColumnNames": [
"Name",
"Weekday",
"Time",
"Type"
],
"Values": [
[
" ",
"1",
"9:00:34",
"OUTGOING"
]
]
}
}
}
It looks like you have an "input" object, containing a string array (ColumnNames) and a two dimensional string array (Values). You could interpret it as a java model object like the following
class Input {
String[] ColumnNames;
Value[][] Values;
}
You can then use a json library like Gson to convert your json to and from this model object, eg new Gson().fromJson(jsonInput, Input.class).
The json you actually have shown us wraps your Input object in two other objects though, so make sure to handle them appropriately.
The JSON result for getUsers I get from the server looks like this:
{
"result": [
{
"meta": {
"rows": "3"
}
},
{
"items": [
{
"id": "1",
"name": "Steve",
"age": "30"
},
{
"id": "2",
"name": "Mary",
"age": "29"
},
{
"id": "3",
"name": "Bill",
"age": "58"
}
]
}
]
}
How can I deserialize it by GSON in my android app (I'm using retrofit)?
I can't imagine any wrapper classes because of the different object types in result.
Any help would be appreciated!
For good example
Converting JSON to Java
Other way, you can convert your json to a java object
Please use org.json library http://www.json.org/java/index.html
Then, for example
json = new JSONObject(YOUR_JSON).getJSONObject("result");
JSONArray items = data.getJSONArray("items");
String name = items.getJSONObject(0).getString("name");
You can write a TypeAdapter for a type that will be (de)serialized to(from) array. You can even make it generic, so it will work with type like Pair<A, B>. Here is an example for non-generic type: https://github.com/cakoose/json-tuple-databinding-examples/blob/master/java/src/GsonEntryCustomizer.java — it (de)serializes Entry to(from array).
Disclaimer — I have not written nor tested that code, but it seems legit.
If you only encounter such problem once (like in your example), you may not bother making it generic, just write TypeAdapter for your specific pair of 2 different classes. The reading code is quite straightforward:
in.beginArray();
SomeClass1 info1 = gson.getAdapter(SomeClass1.class).read(in);
SomeClass2 info2 = gson.getAdapter(SomeClass2.class).read(in);
in.endArray();
return new SomeContainerClass(info1, info2);
(see https://github.com/cakoose/json-tuple-databinding-examples/blob/master/java/src/GsonEntryCustomizer.java#L52)