I am struggling to find a way to read a json file that need to fit into a Map.
So, I have a class ingredients that only contains a String variable ingredient. In another class that is called Recipe I have a Map that will track the ingredients and the amount needed for that particular recipe and a String for the name of the Recipe.
public class Recipe implements Serializable{
private String name;
private Map<Ingredients,Integer> ingredientsList = new HashMap<>();
public Recipe() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<Ingredients, Integer> getIngredientsList() {
return ingredientsList;
}
public void setIngredientsList(Map<Ingredients, Integer> ingredientsList) {
this.ingredientsList = ingredientsList;
}
#Override
public String toString() {
return "Recipe{" +
"name='" + name + '\'' +
", ingredientsList=" + ingredientsList +
'}';
}
}
I have a testClass that contains two methods one to write my recipe to a json file and one to read It from the same json file
#Test
public void writeToJsonFile(){
Ingredients pasta = new Ingredients();
pasta.setName("pasta");
Ingredients bolognaise = new Ingredients();
bolognaise.setName("bolognaise");
Map<Ingredients,Integer>ingredientsIntegerMap = new HashMap<>();
ingredientsIntegerMap.put(pasta,500);
ingredientsIntegerMap.put(bolognaise,600);
Recipe spaghetti = new Recipe();
spaghetti.setName("spaghetti");
spaghetti.setIngredientsList(ingredientsIntegerMap);
Gson gson = new Gson();
try {
FileWriter writer = new FileWriter("src/test/resources/recipe1.json");
writer.write(gson.toJson(spaghetti));
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
#Test
public void readFromJsonFile(){
Gson gson = new Gson();
try {
BufferedReader buffer = new BufferedReader(new FileReader("src/test/resources/recipe1.json"));
Recipe dish =gson.fromJson(buffer, Recipe.class);
System.out.println(dish);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Now my issue is the following when I create a recipe that contains some ingredient and save it to a json fill I don’t have any issue everything works but when I want to load the created Jason file to a recipe it doesn’t work.
this is the error message i get when i try to read the Json file
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 4 column 6 path $.ingredientsList.
Here the Created Json file that contain the recipe
{
"name":"spaghetti",
"ingredientsList":{
"Ingredients{name\u003d\u0027pasta\u0027}":500,
"Ingredients{name\u003d\u0027bolognaise\u0027}":600
}
}
the issue occur due to the Map in the Recipe Class when i remove it or replace it by a List everything works but i would like to use a Map.
can someone help on this issue or recommend another way to track the amount of ingredient for a recipe
thanks
It is a little bit weird that you put as a key in Map an Object that doesn't contain any unique identifier. Maybe it will be better to change Ingredients class to an enum like the following:
public enum Ingredients {
PASTA,
BOLOGNAISE
}
Your JSON will change to:
{
"name":"spaghetti",
"ingredientsList":{
"PASTA":500,
"BOLOGNAISE":600
}
}
Or create an aggregate Object like:
public class IngredientQuantity {
private Ingredient ingredient;
private double quantity;
}
class Ingredient {
private String name;
}
And then replace your map with a simple list:
{
"name": "spaghetti",
"ingredientsList": [
{
"ingredient": {
"name": "PASTA"
},
"quantity": 500
},
{
"ingredient": {
"name": "BOLOGNAISE"
},
"quantity": 600
}
]
}
Parsing arrays in json using Gson.
I have this following json and trying to parse it.
{
"success": true,
"message": "success message",
"data": [
{
"city": "cityname",
"state": "statename",
"pin": 0,
"name" :{
"firstname" : "user"
},
"id" :"emailid"
}],
"status" : "done"
}
So, I have created pojo classes using http://www.jsonschema2pojo.org/
Now, I want to parse the array, for value "city".This is how I did but not sure what is wrong here.
Gson gson = new Gson();
Records obj = gson.fromJson(response,Records.class);
try {
JSONArray jsonArray = new JSONArray(obj.getData());
for(int i=0; i<jsonArray.length(); i++)
{
JSONObject object = jsonArray.getJSONObject(i);
String city = object.getString("city");
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setMessage(city);
dialog.show();
}}
catch (Exception e) {
e.printStackTrace();
}
And this is what getData() is defined in model class:
public class Records {
//////
private ArrayList<Datum> data = null;
public ArrayList<Datum> getData() {
return data;
}
this is not required:
try {
JSONArray jsonArray = new JSONArray(obj.getData());
...
}
catch
...
you just need to do
Records obj = gson.fromJson(response,Records.class);
and then
obj.getData();
would be great if you check that getData() is not null, beacuse something xould go wrong when deserialising
for getting the city: use the getter in the Datum class, you have at the end a list of those obejcts when you call getData
public String getCity() {
return city;
}
I have a method that writes my objects in to a JSON file, is there a way I can read the objects and store them back in to an ArrayList? Ideally I would like to store the objects in to the 'music' ArrayList.
Write to JSON method:
public class TimelineLayout extends JFrame {
private static final long serialVersionUID = 1L;
private JLabel timelineLabel;
static ArrayList<Music> music = new ArrayList<>();
public static void saveMusic(ArrayList<Music> music, String filename) {
String fn;
Gson gson = new Gson();
JsonElement element = gson.toJsonTree(music, new TypeToken<ArrayList<Music>>() {
}.getType());
JsonArray jsonArray = element.getAsJsonArray();
String json = gson.toJson(jsonArray);
try {
//write converted json data to a file named "objects.json"
if (filename != null) {
fn = "objects.json";
} else {
fn = filename + ".json";
}
FileWriter writer = new FileWriter(fn);
writer.write(json);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
JSON Objects:
[{
"artist": "Usher",
"title": "U got it bad",
"genre": "Pop",
"duration": 3.01,
"year": 2003
},
{
"artist": "Coldplay",
"title": "Viva la vida",
"genre": "Rock n ",
"duration": 2.56,
"year": 2001
}
]
Trying to parse using GSON library:
public static List<Music> loadMusic() {
ArrayList<Music> musicList = new ArrayList<>();
Gson gson = new Gson();
JsonParser jsonParser = new JsonParser();
try {
BufferedReader br = new BufferedReader(new FileReader("objects.json"));
JsonElement jsonElement = jsonParser.parse(br);
//Create generic type
java.lang.reflect.Type type = new TypeToken<List<Music>>() {
}.getType();
return gson.fromJson(jsonElement, type);
} catch (IOException e) {
e.printStackTrace();
}
return musicList;
}
Alright, totally new to Android Studio, but I've been trying to parse backpack.tf's json in Android Studio, and I'm a bit stuck.
Here is a little snippet of json I would try to parse:
{
"response": {
"success": 1,
"current_time": 1448658000,
"items": {
"A Color Similar to Slate": {
"last_updated": 1448654419,
"quantity": 48,
"value": 99
},
And the code I'm using to parse JSON is here:
String finalJSON = buffer.toString();
JSONObject parentObject = new JSONObject(finalJSON);
JSONArray parentArray = parentObject.getJSONArray("A Color Similar to Slate");
JSONObject finalObject = parentArray.getJSONObject(3);
int price = finalObject.getInt("value");
return "$" + price;
Thanks a bunch!
Try this:
You have JSON:
{"response":{
"success": 1,
"current_time": 1448658000,
"items": {
"A Color Similar to Slate": {
"last_updated": 1448654419,
"quantity": 48,
"value": 99
},
}
}
}
Code:
String finalJSON =buffer.toString();;
JSONObject parentObject = null;
try {
parentObject = new JSONObject(finalJSON);
JSONObject objectA_Color=parentObject.getJSONObject("response").getJSONObject("items").getJSONObject("A Color Similar to Slate");
int value=objectA_Color.getInt("value");
} catch (JSONException e) {
e.printStackTrace();
}
1) Create some (custom, adjusted to your needs) Model class
public class Model {
private String title;
private List<String> authors;
//getters fields, magic ...
}
2) Parse your JSON (
public static final String JSON_PATH = "/Users/dawid/Workspace/Test/test.json";
Gson gson = new Gson();
BufferedReader br = new BufferedReader(new FileReader(JSON_PATH));
Model model = gson.fromJson(br, Model.class);
OR
1) Parse it with JSON Parser
BufferedReader br = new BufferedReader(new FileReader(JSON_PATH));
JsonParser parser = new JsonParser();
JsonObject object = parser.parse(br).getAsJsonObject();
Both ways Require GSON library https://github.com/google/gson
I'm trying to parse this JSON I get from a HttpURLConnection in Android.
{
"responsejson":
{
"value1": [
{
"data": "Call",
"label": "Call",
"default": false
},
{
"data": "Email",
"label": "Email",
"default": false
}
],
"value2": [
{
"attributes": {
"type": "Status",
"url": "/..."
},
"IsOpened": false,
"IsDefault": true,
"TechLabel": "NotStarted",
"Id": "01Jb"
},
{
"attributes": {
"type": "Status",
"url": "/..."
},
"IsOpened": false,
"IsDefault": false,
"TechLabel": "InProgress",
"Id": "01Jb"
},
{
"attributes": {
"type": "Status",
"url": "/..."
},
"IsOpened": true,
"IsDefault": false,
"TechLabel": "Completed",
"Id": "01Jb"
}
],
...
}
}
What I want to do is save the content of value1 in a string, the content of value2 in another string,... because I need to store it in the database, so in the future I can load and parse it. I am using JsonReader but it's not possible to do this with JsonReader.
// ...
inputStream = conn.getInputStream();
JsonReader json = new JsonReader(new InputStreamReader(in));
json.beginObject();
while (json.hasNext()) {
String valueName = json.nextName();
// String content = ?????
}
json.endObject();
// ...
Any ideas? Custom objects are not possible due to we never know which values the JSON is going to show.
Use this to convert JSON array to string
private String convertStreamToString(InputStream is) {
/*
* To convert the InputStream to String we use the
* BufferedReader.readLine() method. We iterate until the
* BufferedReader return null which means there's no more data to
* read. Each line will appended to a StringBuilder and returned as
* String.
*/
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
Use Gson to parse the JSON that you receive in InputStream. Then you can get the ArrayList from that parsed object. Again, use Gson to serialize the arraylist back to JSON.
This code works for your example json.
public class Value1 {
public String data,label;
#SerializedName("default")
public boolean isdefault;
}
public class Value2 {
public Attributes attributes;
public boolean IsOpened,IsDefault;
public String TechLabel,Id;
}
public class Attributes {
public String type,url;
}
String jsonString = "{\"responsejson\":{\"value1\":[{\"data\":\"Call\",\"label\":\"Call\",\"default\":false},{\"data\":\"Email\",\"label\":\"Email\",\"default\":false}],\"value2\":[{\"attributes\":{\"type\":\"Status\",\"url\":\"/...\"},\"IsOpened\":false,\"IsDefault\":true,\"TechLabel\":\"NotStarted\",\"Id\":\"01Jb\"},{\"attributes\":{\"type\":\"Status\",\"url\":\"/...\"},\"IsOpened\":false,\"IsDefault\":false,\"TechLabel\":\"InProgress\",\"Id\":\"01Jb\"},{\"attributes\":{\"type\":\"Status\",\"url\":\"/...\"},\"IsOpened\":true,\"IsDefault\":false,\"TechLabel\":\"Completed\",\"Id\":\"01Jb\"}]}}";
try {
org.json.JSONObject object = new JSONObject(jsonString);
jsonString = object.getString("responsejson");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(jsonString).getAsJsonObject();
List<Value1> list1 = new Gson().fromJson(obj.get("value1"), new TypeToken<List<Value1>>() {}.getType());
List<Value2> list2 = new Gson().fromJson(obj.get("value2"), new TypeToken<List<Value2>>() {}.getType());
Since you do not know json structure beforehand, your best bet is to use GSON 2.0 feature that supports default maps and lists.
Use the following code to deserialize :
Object object = new Gson().fromJson(jsonString, Object.class);
The created object is a Map (com.google.gson.internal.LinkedTreeMap) which looks like this (for the above example)
{responsejson={value1=[{data=Call, label=Call, default=false}, {data=Email, label=Email, default=false}], value2=[{attributes={type=Status, url=/...}, IsOpened=false, IsDefault=true, TechLabel=NotStarted, Id=01Jb}, {attributes={type=Status, url=/...}, IsOpened=false, IsDefault=false, TechLabel=InProgress, Id=01Jb}, {attributes={type=Status, url=/...}, IsOpened=true, IsDefault=false, TechLabel=Completed, Id=01Jb}]}}
Use the generated object, parse it and save it in your db.
You can serialize that map back to JSON using :
String json = new Gson().toJson(object);
Hope this helps you.
just read the stream regularly and save it into a regular String, then parse that String :
// to get the general object that contains all the values
JSONObject json = new JSONObject(json_readed);
JSONObject response = json.getJSONObject("responsejson");
// to get the values
List<JSONArray> all_values = new ArrayList<JSONArray>();
Iterator<?> keys = response.keys();
while( keys.hasNext() ){
String value = (String)keys.next();
if( response.get(value) instanceof JSONArray ){
all_values.add(response.getJSONArray(value));
}
}
now you have all the values(whatever what's it's name id) combined into that ArrayList called(all_values).
Note that the JSON you provided in your question is missing opening"{" and closing"}" brackets in the beginning and the ending of it.
What you need to do is, first create a JsonObject from the json string representation, at this stage no specifics are given.
JSONObject object = new JSONObject("json_here"); //catch all exceptions thrown.
Interestingly you mentioned that the structure varies, it consider that weird, i am guessing you are pulling from different api instances. What you need to do , create a pojo class mapping the api instance name to the returned json string body.
After you attained the Object of interest, consider using GSON. A Java serialization/deserialization library to convert Java Objects into JSON and back. What you then need to do is to,serialize the pojo class,into an object.Then store into the database. I recommend using realm and not SQLite.
Example serializing the class.
class JClass {
private String jType;
private String json_body;
JClass() {
// no-args constructor
}
}
JClass j = new JClass();
j.jType ="some_type";
j.json_body = "json_body_here";
Gson gson = new Gson();
String json = gson.toJson(j);
then get the json String object, and store in database of choice.
/*
* Method to parse InputStream to String JSON
* */
private String parse(InputStream in){
StringBuilder result;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
Log.d("JSON Parser", "result: " + result.toString());
return result.toString();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
JSONParser parser = new JSONParser();
List<String> output = new ArrayList<String>();
try {
Object obj = parser.parse(data); // data is JSON
JSONObject jsonObject = (JSONObject) obj;
JSONArray msg = (JSONArray) jsonObject.get("value1");
JSONArray msg2 = (JSONArray) jsonObject.get("value2");
Iterator<String> iterator = msg.iterator();
while (iterator.hasNext()) {
output.add(iterator.next());
}
String[] stringArray = output.toArray(new String[0]);
return stringArray;
} catch (Exception e) {
return null;
}