What does the format from json into a list? - java

So basically I'm trying to remove some part of my list, but the problem is because I just got into android development, I don't know the format of the list that I got from JSON file.
Here is the code of my method that retrieve it from a JSON file:
public void getCategory (JSONArray jsonArray, List<ModelCategory> Category){
for (int i = 0; i < jsonArray.length(); i++){
try {
ModelCategory currentCategory = new ModelCategory();
JSONObject jsonObject = jsonArray.getJSONObject(i);
currentCategory.setCategoryID(jsonObject.getInt("idCategory"));
currentCategory.setCategoryName(jsonObject.getString("name"));
Category.add(currentCategory);
kat1.addAll(Category);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Basically, I'm trying to remove the idCategory from the kat1 list. But I don't know what the list looks like. I've read about remove() method from the list, but how do I utilize the method to remove the idCategory?
I'm sorry for the unclear title, I'm pretty new to java development.

Related

Convert JSON to different looking CSV in Java

I need to write a code which would convert JSON file to CSV. The problem is in a format that the CSV file should look like.
Input json:
{
"strings":{
"1level1":{
"1level2":{
"1label1":"1value1",
"1label2":"1value2"
}
},
"2level1":{
"2level2":{
"2level3":{
"2label1":"2value1"
},
"2label2":"2value2"
}
}
}
}
And this is expected csv file for this json:
Keys,Default
1level1.1level2.1label1,1value1
1level1.1level2.1label2,1value2
2level1.2level2.2level3.2label1,2value1
2level1.2level2.2label2,2value2
I was trying to go through JSON file using recursion but this didn't work for me because of rewriting JSON object on each iteration and code was working only till the first value. Are there any suggestions about how can it be done?
Note: have tried to use different JSON libraries, so for now can be used any of them
UPDATE #1:
Non-working code example I was trying to use to go through JSON tree:
public static void jsonToCsv() throws JSONException {
InputStream is = MainClass.class.getResourceAsStream("/fromJson.json");
JSONTokener jsonTokener = new JSONTokener(is);
JSONObject jsonObject = new JSONObject(jsonTokener);
stepInto(jsonObject);
}
private static void stepInto(JSONObject jsonObject) {
JSONObject object = jsonObject;
try {
Set < String > keySet = object.keySet();
for (String key: keySet) {
object = object.getJSONObject(key);
stepInto(object);
}
} catch (JSONException e) {
Set < String > keySet = object.keySet();
for (String key: keySet) {
System.out.println(object.get(key));
}
e.printStackTrace();
}
}
UPDATE #2:
Another issue is that I will never know the names of the JSON object and count of child objects (update JSON and CSV examples as well to make the image more clear). All that is known, that it will always start with strings object.
Library used:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180813</version>
</dependency>
So found a solution by myself:
public static void jsonToCsv() throws JSONException, IOException {
InputStream is = MainClass.class.getResourceAsStream("/fromJson.json");
JSONTokener jsonTokener = new JSONTokener(is);
JSONObject jsonObject = new JSONObject(jsonTokener).getJSONObject("strings");
builder = new StringBuilder();
while (!jsonObject.isEmpty()) {
stepInto(jsonObject);
}
String[] lines = builder.toString().split("\n"); // builder lines are in reverse order from expected so this array is used to reverse them
FileWriter csvWriter = new FileWriter("src/main/resources/toCsv.csv");
csvWriter.append("Keys,Default (en_US)\n");
for (int i = lines.length - 1; i >= 0; i--) {
csvWriter.append(lines[i]).append("\n");
}
csvWriter.flush();
csvWriter.close();
}
private static void stepInto(JSONObject jsonObject) {
for (String key: jsonObject.keySet()) {
Object object = jsonObject.get(key);
if (object instanceof JSONObject) {
builder.append(key).append(".");
stepInto(jsonObject.getJSONObject(key));
} else {
builder.append(key).append(",").append(object).append("\n");
jsonObject.remove(key);
break;
}
if (jsonObject.getJSONObject(key).isEmpty()) {
jsonObject.remove(key);
}
break;
}
}
I think you just missed keeping track of your result, otherwise it looks good.
Let's say your result is a simple string. Then you have to concatenate all keys while traversing the json object until you reach a primitive value (like a number or a string).
(I am writing this out of my head, so please forgive me for incorrect syntax)
private static String stepInto(JSONObject jsonObject) { // we change "void" to "String" so we can record the results of each recursive "stepInto" call
//JSONObject object = jsonObject; // we don't need that. Both variables are the same object
String result ="";
try {
for (String key: jsonObject.keySet()) { // shorter version
Object object = jsonObject.get(key); // Attention! we get a simple Java Object
if(object instanceof JSONObject){
result+= key+"."+stepInto(jsonObject.getJSONObject(key)); // the recursive call, returning all keys concatenated to "level1.level2.level3" until we reach a primitive value
}
if(object instanceof JSONArray){
result+= key+", "+ ... // notice how we use the csv separator (comma) here, because we reached a value. For you to decide how you want to represent arrays
}
result+= key +", "+ object +"\n"; // here I am not sure. It may well be that you need to check if object is a String an Integer, Float or anything.
}
} catch (JSONException e) {
for (String key: jsonObject.keySet()) {
System.out.println(object.get(key));
}
e.printStackTrace();
result+= "\n"; // I added this fallback so your program can terminate even when an error occurs.
}
return result; // sorry, I forgot to accumulate all results and return them. So now we have only one actual "return" statement that will terminate the call and return all results.
}
As you can see, I didn't change much of your original method. The only difference is that now we keep track of the keys ("level1.level2...") for each recursive call.
EDIT
I added a +"\n"; so everytime we reach a value so we can terminate that "line".
AND more importantly, instead of returning everytime, I add the result of each call to a string, so we continue looping over the keys and concatenate all results. Each call of the method will return only once all keys are looped over. (sorry that missed that)
In your calling method you could print out the result, something like that:
JSONObject jsonObject = new JSONObject(jsonTokener);
String result = stepInto(jsonObject);
System.out.println(result);

Create an Array string for table layout

I want to pass a list of data from my php to populate my table layout, am presently using volley to connect to my server side. How do i set this list
Am making use of codecrafters library and they have a tutorial on how to populate the table which works for me but the problem is the items they used were manually typed and not gotten dynamically from a server, so am having issues implementing this same code for data that comes from a server
Their string looks like this
static String[][] spaceProbes={
{"1","Pioneer","Chemical","Jupiter"},
{"2","Voyager","Plasma","Andromeda"},
{"3","Casini","Solar","Saturn"},
{"4","Spitzer","Anti-Matter","Andromeda"},
{"5","Apollo","Chemical","Moon"},
{"6","Curiosity","Solar","Mars"},
};
and they populate it into the layout using
tableView.setDataAdapter(new SimpleTableDataAdapter(MainActivity.this, spaceProbes));
am presently using this array string but it returns the last item in the array only
try {
//converign the strign to json assary object
JSONArray array = new JSONArray(response);
//traversing through all teh objects
for (int i = 0; i < array.length(); i++) {
//getting product object from json array
JSONObject allClass = array.getJSONObject(i);
takin = new String[]{allClass.getString("numb"),
allClass.getString("name"),
allClass.getString("time")};
}
tableView.setDataAdapter(new SimpleTableDataAdapter(AttendanceActivity.this, Collections.singletonList(takin)));
} catch (JSONException e) {
e.printStackTrace();
}
How do i recreate the same structure as spaceProbes but this time from the server
You reset the value of takin every time when you do
takin = new String[]{allClass.getString("numb"),
allClass.getString("name"),
allClass.getString("time")};
Instead, try this,
String[][] takin = new String[array.length()][3]
for (int i = 0; i < array.length(); i++) {
JSONObject allClass = array.getJSONObject(i);
takin[i] = new String[]{allClass.getString("numb"),
allClass.getString("name"),
allClass.getString("time")};
}
tableView.setDataAdapter(new SimpleTableDataAdapter(AttendanceActivity.this, Collections.singletonList(takin)));

Java - JSONArray has 10 objects but only display first two

I'm new to Android and Java so I'm building a demo app of book listing to learn about parsing JSON data. I use log to check how many books there are on data (which is 10 ) but only get 2 first books on the list displayed when running it on an emulator... Hope anyone can tell me where I should change?
Thanks for any opinion!
E/QueryUtils: length of array: 10
The API link: https://www.googleapis.com/books/v1/volumes?q=search+terms
QueryUtils.java
private static List<BookItem> extractItemFromJson(String bookJSON) {
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(bookJSON)){
return null;
}
// Create an empty ArrayList that we can start adding books to
List<BookItem> bookItems = new ArrayList<>();
// Try to parse the JSON response string. If there is a problem with the way the JSON is formatted,
// a JSONException exception object will be thrown.
// Catch the exception so the app doesnt crash, and prent the error message to the logs.
try {
JSONObject baseJsonresponse = new JSONObject(bookJSON);
JSONArray bookItemArray = baseJsonresponse.getJSONArray("items");
Log.e("QueryUtils", "length of array: " + bookItemArray.length());
for (int i = 0; i < bookItemArray.length(); i++) {
JSONObject currentBook = bookItemArray.getJSONObject(i);
JSONObject volumeInfo = currentBook.getJSONObject("volumeInfo");
String title = volumeInfo.getString("title");
String subtitle = volumeInfo.getString("subtitle");
String previewLink = volumeInfo.getString("previewLink");
JSONObject imageLinks = volumeInfo.getJSONObject("imageLinks");
String thumbnail = imageLinks.getString("smallThumbnail");
BookItem book = new BookItem(/**author, */title, subtitle, thumbnail, previewLink);
bookItems.add(book);
}
} catch (JSONException e) {
Log.e("QueryUtils", "Problem parsing the earthquake JSON results", e);
}
return bookItems;
}
The third book in your list does not cointain the field imageLinks, and that causes an exception.
You should add a check:
String thumbnail = "";
if (volumeInfo.has("imageLinks")) {
JSONObject imageLinks = volumeInfo.getJSONObject("imageLinks");
thumbnail = imageLinks.getString("smallThumbnail");
}
I suspect it's going to the catch block after parsing the first 2 because an exception happened while parsing, You should fix the exception and also you can catch the exception inside the loop to add the items that could be parsed and don't quit the loop if there is a JSONException.

Value 91 at 0 of type java.lang.Byte cannot be converted to JSONObject

I'm getting the following error:
org.json.JSONException: Value 91 at 0 of type java.lang.Byte cannot be converted to JSONObject
And it's because of this line of code:
JSONObject jObj = j.getJSONObject(i);
I'm doing a GET request and I logged it in Android Studio which looks like this:
jsonarray [91,109,111,100,101,108,46,83,116,111,114,101,64,52,57,57,54,102,97,56,44,32,109,111,100,101,108
In the browser it looks like this:
Link to a screenshot: http://i.imgur.com/NTpwbuB.png
I had used a JSONObject, because I want to do later something like this:
String storeName = jObj.getString("STORE NAME");
String street = jObj.getString("STREET");
String city = jObj.getString("CITY");
Here is the code:
public void getSubprises() {
Call<List<Store>> call = subpriseAPI.listStores();
call.enqueue(new Callback<List<Store>>() {
#TargetApi(Build.VERSION_CODES.KITKAT)
#Override
public void onResponse(Response<List<Store>> response, Retrofit retrofit) {
try {
JSONArray j = new JSONArray(response.body().toString().getBytes());
System.out.println("jsonarray "+ j);
for (int i = 0; i < j.length(); i++) {
JSONObject jObj = j.getJSONObject(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable t) {
}
});
}
just change
JSONArray j = new JSONArray(response.body().toString().getBytes());
to
JSONArray j = new JSONArray(response.body().toString());
i think this is what you want to do.
If this didn't work, then you really don't know what the response body has inside, to learn use System.out.print function to see what response.body().toString() prints.
if it is something like
[
{"STORE_NAME" : "abc", "STREET" : "def"}, {"STORE_NAME" : "asw", "STREET" : "rew" }
]
everything is well. Else you need to change the way you get the jsonobject.
EDIT:
["model.Store#4996fa8","model.Store#949eac1","model.Store#c45f266", ...
this output that you wrote in the comments made me realize that you don't need a JSONArray or anything, Response> response already has the Store objects.
And looking that output, response.body() returns List,
then you can do this to get the outputs
EDIT 2:
java.util.Iterator it=response.body().iterator();
while(it.hasNext())
System.out.println(((Store)it.next()).getStreet());
Above code will only work if the Store object has the method getStreet of course if not you can use st.street or st. then ctrl+space and find the street like label there.

Modifying/Updating values inside a jsonArray?

What I want to do is at a particular index position change/replace a value inside a json array.After going through the documentation at http://www.json.org/javadoc/org/json/JSONArray.html I found out that jsonArray does not have a getIndex() method.In this situation how do I update my json array at a given index position.
This is the method that creates a json array in my android code.
private void createJsonArray() {
billType = (invEstSwitch.isChecked() ? textViewEstimate : textViewInvoice)
.getText().toString();
String invNumber = textViewInvNo.getText().toString();
String bcode = barCode.getText().toString();
String description = itemDesc.getText().toString();
String wt = weightLine.getText().toString();
String rateAmt = rateAmount.getText().toString();
String making = makingAmount.getText().toString();
String netr = netRate.getText().toString();
String iTotal = itemtotal.getText().toString();
String vatAmt = textViewVat.getText().toString();
String sumAmt = textViewSum.getText().toString();
String crtDate = textViewCurrentDate.getText().toString();
try {
jsonObject.put("custInfo", custSelected.toString());
jsonObject.put("invoiceNo", invNumber);
jsonObject.put("barcode", bcode);
jsonObject.put("description", description);
jsonObject.put("weight", wt);
jsonObject.put("rate", rateAmt);
jsonObject.put("makingAmt", making);
jsonObject.put("net_rate", netr);
jsonObject.put("itemTotal", iTotal);
jsonObject.put("vat", vatAmt);
jsonObject.put("sum_total", sumAmt);
jsonObject.put("bill_type", billType);
jsonObject.put("date", crtDate);
} catch (JSONException e) {
e.printStackTrace();
}
try {
itemSelectedJson.put(index, jsonObject);
index++;
} catch (JSONException e) {
e.printStackTrace();
}
}
And this is the code that I use to update my json array which contains a json object.
try {
itemSelectedJson.getJSONObject(i).put("net_rate",netChange);
Log.d("NETRATE_TW",itemSelectedJson.toString());
} catch (JSONException e) {
e.printStackTrace();
}
Now the problem with this code is it updates the jsonArray everytime a new item is added to the code.So the first object values are the same as the last object.
Also note that I am using this code inside a text watcher.So the afterTextchanged() method looks like this.
#Override
public void afterTextChanged(Editable s) {
String netChange = netRate.getText().toString();
final int row_id = (int) newRow.getTag();
if ((row_id<0) || (row_id> itemSelectedJson.length())){
return;
}
try {
itemSelectedJson.getJSONObject(row_id-1).put("net_rate",netChange);
Log.d("NETRATE_TW",itemSelectedJson.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
};
This is the snapshot of what my database looks like.
A jSONObject(which is a collection of name,value pairs) can be converted into a JSONArray which is an ordered array of the "values" in the JSONObject.
This can be done using the .toJSONArray() method.
When you need to replace/update the JSONArray, you may use the method
.put(int index, java.util.Map value)
Unlike how you are doing at present, i.e getting the object and setting a new key and value.
http://www.json.org/javadoc/org/json/JSONArray.html#put(int, java.util.Map)
As I understood, your problem is in creating multiple JSONObjects in your JSONArray with the same values, and that's because you can't get the index of a created JSONObject inside your JSONArray, and to overcome this problem, you can easily create a compound JSONObject that contains your JSONObjects instead of a JSONArray contains JSONObjects, and the object name will be anything unique in your JSONObject data, and when you make any changes or add any item it will either be added as a new object if it doesn't exist or it will overwrite the existing object if it added before, for example let's suppose that barcode value is unique in your data, so the code will be like the following:
// declaring itemSelectedJson as JSONObject
JSONObject itemSelectedJson = new JSONObject();
.
.
.
// when wanting to add a new item
itemSelectedJson.put(jsonObject.getString("barcode"), jsonObject);
and to retrieve the data you simple iterate through this JSONObject:
Iterator<?> keys = itemSelectedJson.keys();
JSONObject single_item;
while(keys.hasNext()) {
String key = (String)keys.next();
single_item = itemSelectedJson.getJSONObject(key);
// do what do you want here
}

Categories