JSON deserialization with Gson - java

This is my JSON data:
{
"boards": [
{
"board": "3",
"title": "3DCG",
"ws_board": 1,
"per_page": 15,
"pages": 11
},
{
"board": "a",
"title": "Anime & Manga",
"ws_board": 1,
"per_page": 15,
"pages": 11
},
{
"board": "adv",
"title": "Advice",
"ws_board": 1,
"per_page": 15,
"pages": 11
},
...
]
}
This is my code for deserialization:
JSONObject json = readJsonFromUrl("http://api.4chan.org/boards.json");
String jsonBoards = json.toString();
Gson gson = new Gson();
Map<String, Object> map = new HashMap<String,Object>();
map = (Map<String,Object>) gson.fromJson(jsonBoards, map.getClass());
But it doesn't get the job done. I need a way to get the boards name, title, and all the that information for each board. When I use map.get(); the key is "boards" but I want a map of every board and title and so on.

You need a class structure that maps your JSON data. You don't need to use a Map anywhere, since your JSON does not represent any map!
In fact it represents an object {...} that contains a field called "boards", which in turn represents an array [...] of objects {...}...
So the class structure that matches your JSON would be something like this (in pseudo-code):
class Response
List<Board> boards
class Board
String board
String title
int ws_board
int per_page
int pages
Then, in order to parse the JSON into your class structure, you just need to do this:
Gson gson = new Gson();
Response response = gson.fromJson(jsonBoards, Response.class);
So you'll have all the data of all your boards into:
String nameI = response.getBoards().get(i).getName();
String titleI = response.getBoards().get(i).getTitle();
//and so on...

Related

Parse JSON file to java objects using Gson

I am having issues with "converting" the data in the JSON file to the required java objects. The JSON file looks something like this:
{
"initialInventory": [
{"bookTitle": "Harry Poter", "amount": 10, "price": 90},
{"bookTitle": "The Hunger Games", "amount": 90, "price": 102}
],
"initialResources":[
{"vehicles":[
{"license":123483, "speed": 2},
{"license":999994, "speed": 4}
]
}
],
"services":{
"time": {
"speed": 1000,
"duration": 24
},
"selling": 6,
"inventoryService": 3,
"logistics": 4,
"resourcesService": 2,
"customers": [
{
"id": 123456789,
"name": "Bruria",
"address": "NewYork 123",
"distance":33,
"creditCard":{"number":67890,"amount":88},
"orderSchedule": [
{"bookTitle": "Harry Poter", "tick": 3},
{"bookTitle": "The Hunger Games", "tick": 3}
]
},
{
"id": 234567891,
"name": "Shraga",
"address": "BeerSheva 3333",
"distance":12,
"creditCard":{"number":453536,"amount":220},
"orderSchedule": [
{"bookTitle": "The Hunger Games", "tick": 12}
]
}
]
}
All the JSON files I will be dealing with (for now) have the same structure.
I tried using Gson to parse the file (I am required to use Gson for this),
I've searched many videos and tutorials regarding the matter, but most of them were over-simplified or simply irrelevant, and it feels like either there are too many ways to do it, or that I just can't understand how to do it correctly.
This is what I tried so far:
public class BookStoreRunner {
public static void main(String[] args) throws IOException { //has to be added, we get an error without it. can be dealt with try-catch, doesn't matter.
Gson gson=new Gson();
File jsonfile= new File("pathtofile"); //should be the actual path to the file.
InputStream iStream= new FileInputStream(jsonfile);
Reader reader = new InputStreamReader(iStream);
JsonReader jsonReader =gson.newJsonReader(reader);
JsonParser parser= new JsonParser();
BookInventoryInfo[] books=gson.fromJson("initialInventory",BookInventoryInfo[].class);
ResourcesHolder.getInstance().load(gson.fromJson("vehicles",DeliveryVehicle[].class));
int timespeed= gson.fromJson("speed",int.class);
int timeduration=gson.fromJson("duration",int.class);
int numOfSellers=gson.fromJson("selling",int.class);
int numOfInventories=gson.fromJson("inventoryService",int.class);
int numOfLogistics=gson.fromJson("logistics",int.class);
int numOfResourceServices=gson.fromJson("resourcesService",int.class);
Customer[] customers=gson.fromJson("customers",Customer[].class);
/* JsonElement jElement = parser.parse(reader); // JsonElement is equivalent to a list in java
JsonObject jObject = jElement.getAsJsonObject(); //equivalent to an object of a class that implements the 'map' interface, e.g contains pairs of key:value
JsonObject initialInventory = jObject.getAsJsonObject("initialInventory");
JsonArray inventory =initialInventory.getAsJsonArray(); //it is an array (json syntax), but a JSONArray is not iterable.
// dealing with inventory
int i=0; //counter for all the books to be inserted to inventory array (index)
for (Map.Entry<String,JsonElement> entry: initialInventory.entrySet()) //.entrySet() gives a set view of the JSONObject, which is iterable
{
}
JsonArray iResources= jObject.getAsJsonArray("initialResources");
JsonObject veh = iResources.get(0).getAsJsonObject();
//initialization of java object, for the initialResources
JsonObject services=jObject.getAsJsonObject("services");
JsonObject timedata=jObject.getAsJsonObject("services").getAsJsonObject("time");
int numOfSelling= gson.fromJson(jObject.getAsJsonObject("services").getAsJsonPrimitive("selling"), int.class);
int numOfInventories= gson.fromJson(jObject.getAsJsonObject("services").getAsJsonPrimitive("inventoryService"), int.class);
int numOfIogistics=gson.fromJson(jObject.getAsJsonObject("services").getAsJsonPrimitive("logistics"),int.class);
int numOfResourceServices= gson.fromJson(jObject.getAsJsonObject("services").getAsJsonPrimitive("resourcesService"),int.class);
JsonArray jsonCustomers = jObject.getAsJsonObject("services").getAsJsonArray("customers");
JsonObject jsonCustomersObject=jObject.getAsJsonObject("services").getAsJsonObject("customers");
Customer[] customers = new Customer[5000]; // check if there's a problem with this part. unsure how many customers there are, or if we need\can use a list.
int i=0; //customers index
for (Map.Entry<String,JsonElement> entry: jsonCustomersObject.entrySet())
{ //assuming we will implement a constructor for Customer which receives all the required values
}
*/
I've tried parsing the file with a different approach, it's marked as a comment at the end of the code.
I can't figure out if the problem is with my understanding of JSON in general, my knowledge of java I\O usage or that I'm simply missing something.
How can I create the Objects I need from the JSON file effectively with Gson?

Need some assistance trying to parse this JSON response from our backend server

Currently working on an android app and I need help on how I can go about extracting the subfields within the responses field of this json object:
Currently I am doing the following to extract some of the other fields:
JSONObject json = new JSONObject(response2);
int id = json.getInt("id");
String desc = json.getString("description");
JSONObject json2 = json.getJSONObject("owner");
String username = json2.getString("userName");
You need to create logic to parse the data. Every item from the JSON string is in the JSONObject you created with
JSONObject json = new JSONObject(response2);
You're on the right track with what you're doing. Just use the corresponding methods available in JSONObject and JSONArray classes to move through the object.
Start with the main object
{ // <-- this is your main object (AKA JSONObject json = new JSONObject(response2))
"id": 1, // to pull this id use json.getInt("id");
"title": "some text here", // to pull this title use json.getString("title");
...
"owner": { // Here's the logic part, owner is itself, a JSON object. so now you must extract it and parse through it.
// to pull the "owner" JSON object, use JSONObject ownerObject = json.getJSONObject("owner");
"userId": 1, // Now use the ownerObject to pull it's values. ownerObject.getInt("userId");
"userName": "TestingUser", // to pull this userName use ownerObject.getString("userName");
...
}
...
}
If it's an array, for example:
"someJSONArray": [{ "id": 1, "userName": "TestingUser1" }, { "id": 2, "userName": "TestingUser2" }]
then you would call:
JSONArray someJSONArray = getJSONArray("someJSONArray");
// Get each object from the array.
JSONObject object1 = someJSONArray.getJSONObject(0);
JSONObject object2 = someJSONArray.getJSONObject(1);
or if the array contains a string, for example:
"someKey": [ 23, 435, 123, 6345, 123 ]
then you would call:
JSONArray someKeyArray = getJSONArray("someKey");
for (int i = 0; i < someKeyArray.length(); i++) {
// Extract the value.
int itemValue = someKeyArray.getInt(i);
}
The data is there, you just have to parse it.

Searching JSon string using java

I am new To JSon and i want to search the following json string and get the required output.
String:
{"status":"Success","code":"200","message":"Retrieved Successfully","reason":null,"
"projects":
[
{
"projectName": "example",
"users":
[
{
"userName": "xyz",
"executions":
[
{
"status": "check",
"runs":
[
{
"Id": "------",
"Key": "---"
}
],
"RCount": 1
}
],
"RCount": 1
}
],
"RCount": 1
},
Like that i have many projects and now , if i give projectname and username as input i wantt to get its status as output.
Is it possible?If yes how?
You may use JSONObject for this.
JSONObject json = new JSONObject(string);
JSONArray[] projectsArray = json.getJSONArray("projects");
for(int i = 0; i < projectsArray.length; ++i)
{
String projectName = projectsArray[i].getString("projectName");
...
}
Use the same method to get the users.
You can use gson library. Using gson convert your json string to Map and then you can iterate through map to get required item
Type type = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> myMap = gson.fromJson(jsonString, type);
You can use the Google gson to map your json data structure to a Java POJOs.
Example :
You can have Projects class containing list/array of Users.
Users class containing list/array of Executions and so on.
Gson library can easily map the json to these classes as objects and you can access your data in a more elegant manner.
Here are a few references :
http://howtodoinjava.com/2014/06/17/google-gson-tutorial-convert-java-object-to-from-json/
http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/

JSON To ArrayList<CustomObject> With GSON While Ignoring Certain Fields

I am looking to create an ArrayList of custom objects from a JSON feed using GSON. My current approach works fine for a single JSON object holding an array, but now I need to parse a more complex JSON object. The first JSON feed looked like this:
{"data":
{"item_id": "1", "element": "element1"}
{"item_id": "2", "element": "element2"}
{"item_id": "3", "element": "element3"}
...
}
My method for extracting each item was using a simple custom object and parsing the JSON into an ArrayList of these objects.
InputStreamReader input = new InputStreamReader(connection.getInputStream());
Type listType = new TypeToken<Map<String, ArrayList<CustomObject>>>(){}.getType();
Gson gson = new GsonBuilder().create();
Map<String, ArrayList<CustomObject>> tree = gson.fromJson(input, listType);
ArrayList<CustomObject> = tree.get("data");
The current JSON object looks like this:
{"rate_limit": 1, "api_version": "1.2", "generated_on": "2015-11-05T19:34:06+00:00", "data": [
{"collection": [
{"item_id": "1", "time": "2015-11-05T14:40:55-05:00"},
{"item_id": "2", "time": "2015-11-05T14:49:09-05:00"},
{"item_id": "3", "time": "2015-11-05T14:51:55-05:00"}
], "collection_id": "1"},
{"collection": [
{"item_id": "1", "time": "2015-11-05T14:52:01-05:00"},
{"item_id": "2", "time": "2015-11-05T14:49:09-05:00"},
{"item_id": "3", "time": "2015-11-05T14:51:55-05:00"}
], "collection_id": "2"
]}
And I am having trouble parsing it because of the mixed types of data, some are numbers, strings and lastly arrays. I have a custom object built that takes an array of another custom object. This is the collection object:
public class CustomCollection {
private String collection_id;
private ArrayList<CustomItem> collection_items = new ArrayList<>();
public CustomCollection() {
this(null, null);
}
public CustomCollection(String id, ArrayList<CustomItem> items) {
collection_id = id;
collection_items = items;
}
public String getId() {
return collection_id;
}
public ArrayList<CustomItem> getItems() {
return collection_items;
}
}
And this is the item object:
public class CustomItem {
private String item_id;
private String item_element;
public CustomItem() {
this(null, null);
}
public CustomItem(String id, String element) {
item_id = id;
item_element = element;
}
public String getId() {
return item_id;
}
public String getElement() {
return item_element;
}
}
I do not really care about obtaining the other elements (i.e. "rate_limit", "api_version", "generated_on"), I just want to pass the "data" element into an ArrayList of objects. But when I try something similar to my original method, the parser stops a the first object because it receives a number instead of an array. Resulting in an IllegalStateException: Expected BEGIN_ARRAY but was NUMBER at line 1 column 17 path $.. I would like to know how I can either get the parser to ignore the other elements, or how I can get each element separately using GSON.
EDIT: The proposed solution to my problem, found in Ignore Fields When Parsing JSON to Object, technically does solve my issue. But this seems like a lengthy process that is unnecessary in my case. I have found a much simpler solution to my problem, posted in my answer below. I am also unsure if this method would work well for the aforementioned question, considering there does not seem to be a way to get a JsonObject from a JsonArray by key name in GSON.
The solution I have found is to parse the data into a com.google.gson.JsonObject, then into a JsonArray by key name. I can then use this JsonArray as a parameter in Gson.fromJson() to extract the data into my ArrayList of custom objects.
InputStreamReader input = new InputStreamReader(connection.getInputStream());
JsonArray data = new JsonParser().parse(input).getAsJsonObject().getAsJsonArray("data");
Type listType = new TypeToken<ArrayList<CustomCollection>>(){}.getType();
ArrayList<CustomCollection> collection = new Gson().fromJson(data, listType);
input.close();
This method ignores all other JSON fields, only obtaining the one specified. It also takes the array of objects from within the "data" object and puts them into the ArrayList of custom objects within CustomCollection.

Parse json string for specific value using JSONObject

In java, I am trying to parse values from this json..
[
{
"2012-01-02": {
"age": 3,
"dob": "2010-01-03",
"name": "jack"
},
"2012-01-03": {
"age": 3,
"dob": "2010-01-04",
"name": "jill"
},
"2012-01-04": {
"age": 3,
"dob": "2010-01-05",
"name": "john"
},
"2012-01-05": {
"age": 3,
"dob": "2010-01-06",
"name": "miran"
}
}
]
Using JSONObject, I was trying to get the value of just "age" and then add them up to do some data manipulation.
I created a JSONObject
Created an iterator and then stored them to a map
This gets me the inner element like:
{
"age": 3,
"dob": "2010-01-06",
"name": "miran"
}
After this, not sure how to extract just age from each element. Do i create another jsonobject and pass this new string, extract age out of it or is there a better way to do this? (I am sure there is one)
UPDATE:
This is what I currently have that gives me {"age":3,"dob":"2012-01-06","name":"miran"}
JSONObject jsonobj = new JSONObject();
try {
jsonobj = new JSONObject(pastweekVol);
Iterator iter = jsonobj.keys();
Map<String, String> map = new HashMap<String, String>();
while(iter.hasNext()){
String jsonkey = (String)iter.next();
String value = jsonobj.getString(jsonkey);
logger.debug("first pass value is: {}", value);
} catch (JSONException je) {
logger.debug("exception is: {}",je);
}
I was thinking that since I am getting {"age":3,"dob":"2012-01-06","name":"miran"}, I would create another json object and pass in this string, which will give me value of "age". The problem here is that I get repetitive values. Of course, something very basic is missing here but I can't seem to figure that out.
If you have the inner element as a JSONObject instance - say person - then you can directly access the age:
int age = person.getInt("age");
and do something with it:
sum += age;
You might consider a library like Google's GSON (http://code.google.com/p/google-gson/) if you want to be able to easily parse arbitrarily complex JSON strnigs into generic objects.
Using org.json is probably not your best bet -- this API has many flaws. Using Jackson, you can easily extract age from each member value:
ObjectMapper mapper = new ObjectMapper();
JsonNode fullDocument = mapper.readTree(xxx); // xxx can be many things
// Not an object? Bail out
if (!fullDocument.isObject())
throw new IllegalArgumentException("not an object");
// This will iterate through object values
for (JsonNode value: fullDocument)
// do something with value.get("age")
// in particular, you can test for .isIntegralNumber()

Categories

Resources