This is a working example based (and tested) with gson-2.8.0. It accepts an arbitrary sequence of JSON objects on a given input stream. And, of course, it does not impose any restrictions on how you have formatted your input:
InputStream is = /* whatever */
Reader r = new InputStreamReader(is, "UTF-8");
Gson gson = new GsonBuilder().create();
JsonStreamParser p = new JsonStreamParser(r);
while (p.hasNext()) {
JsonElement e = p.next();
if (e.isJsonObject()) {
Map m = gson.fromJson(e, Map.class);
/* do something useful with JSON object .. */
}
/* handle other JSON data structures */
}
Answer from wh81752 on Stack OverflowThis is a working example based (and tested) with gson-2.8.0. It accepts an arbitrary sequence of JSON objects on a given input stream. And, of course, it does not impose any restrictions on how you have formatted your input:
InputStream is = /* whatever */
Reader r = new InputStreamReader(is, "UTF-8");
Gson gson = new GsonBuilder().create();
JsonStreamParser p = new JsonStreamParser(r);
while (p.hasNext()) {
JsonElement e = p.next();
if (e.isJsonObject()) {
Map m = gson.fromJson(e, Map.class);
/* do something useful with JSON object .. */
}
/* handle other JSON data structures */
}
I know it has been almost one year for this post :) but i am actually reposing again as an answer because i had this problem same as you Yuan
I have this text.txt file - I know this is not a valid Json array - but if you look, you will see that each line of this file is a Json object in its case alone.
{"Sensor_ID":"874233","Date":"Apr 29,2016 08:49:58 Info Log1"}
{"Sensor_ID":"34234","Date":"Apr 29,2016 08:49:58 Info Log12"}
{"Sensor_ID":"56785","Date":"Apr 29,2016 08:49:58 Info Log13"}
{"Sensor_ID":"235657","Date":"Apr 29,2016 08:49:58 Info Log14"}
{"Sensor_ID":"568678","Date":"Apr 29,2016 08:49:58 Info Log15"}
Now I want to read each line of the above and parse the names "Sensor_ID" and "Date" into Json format. After long search, I have the following:
Try it and look on the console to see the result. I hope it helps.
package reading_file;
import java.io.*;
import java.util.ArrayList;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class file_read {
public static void main(String [] args) {
ArrayList<JSONObject> json=new ArrayList<JSONObject>();
JSONObject obj;
// The name of the file to open.
String fileName = "C:\\Users\\aawad\\workspace\\kura_juno\\data_logger\\log\\Apr_28_2016\\test.txt ";
// This will reference one line at a time
String line = null;
try {
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(fileName);
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader = new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null) {
obj = (JSONObject) new JSONParser().parse(line);
json.add(obj);
System.out.println((String)obj.get("Sensor_ID")+":"+
(String)obj.get("Date"));
}
// Always close files.
bufferedReader.close();
}
catch(FileNotFoundException ex) {
System.out.println("Unable to open file '" + fileName + "'");
}
catch(IOException ex) {
System.out.println("Error reading file '" + fileName + "'");
// Or we could just do this:
// ex.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I would like to save/load two List objects to a single json file. Can I read/write them in succession somehow or do I have to make a wrapper class first and then read/write the wrapper class?
How to read JSON with multiple objects java - Stack Overflow
In Java, How do I represent multiple objects (of same type) in a single JSON object
java - How to Parse a JSON object with contains multiple JSON objects ( not an array) of the same type - Stack Overflow
java - How to create multiple JSON objects via for loop - Stack Overflow
Your json fragment is invalid - the last comma breaks the parsing. But the rest of the code is quite workable.
String res = "[\n" +
" {\n" +
" \"Class\": \"1\",\n" +
" \"school\": \"test\",\n" +
" \"description\": \"test\",\n" +
" \"student\": [\n" +
" \"Student1\",\n" +
" \"Student2\"\n" +
" ],\n" +
" \"qualify\": true,\n" +
" \"annualFee\": 3.00\n" +
" }\n" +
"]";
JSONArray arr = new JSONArray(res);
for (int i = 0; i < arr.length(); i++) {
JSONObject block = arr.getJSONObject(i);
Integer cls = block.getInt("Class");
System.out.println("cls = " + cls);
Object school = block.getString("school");
System.out.println("school = " + school);
JSONArray students = block.getJSONArray("student");
System.out.println("student[0] = " + students.get(0));
System.out.println("student[1] = " + students.get(1));
}
should output
cls = 1
school = test
student[0] = Student1
student[1] = Student2
Your JSON reponse root is array but you consider your JSON response as JSON object
Changing your parsing json code as below
String res=cspResponse.prettyPrint();
org.json.JSONArray arr = new org.json.JSONArray(res);
String dataStatus=null;
for (int i = 0; i < arr.length(); i++) {
org.json.JSONObject obj=arr.getJSONObject(i);
dataStatus = obj.getString(key);
System.out.println("dataStatus is \t" + dataStatus);
String schoolName = org.getString("school");
System.out.println("school => " + schoolName);
org.json.JSONArray students = obj.getJSONArray("student");
System.out.println("student[0] = " + students.get(0));
System.out.println("student[1] = " + students.get(1));
}
What you're doing is the correct way to do it. JSON calls always return one object.
The object you got back is an array, so you can extract the elements like this:
var myResponse = makeJSONCall();
// You have received myResponse.length objects, you can bind them
// to variables if you want
var thingOne = myResponse[0];
var thingTwo = myResponse[1];
...
// You can use them from their variable names or straight from the array
thingOne.name = "Joe Bob";
myResponse[3].status = "Tired";
using json lib
List mybeanList = new ArrayList();
mybeanList.add(myBean1);
mybeanList.add(myBean2);
JSONArray jsonArray = JSONArray.fromObject(mybeanList);
You can also use XStream to do this
See Also
- Google gson
Java variable names cannot be constructed dynamically.
I don't know how no one has answered this yet but here you are.
JSONObject objects = new JSONObject[10];
for(int i = 0 ; i < objects.length ; i++) {
objects[i] = new JSONObject();
}
JSONObject o = objects[2]; // get the third one
Arrays are not dynamically resizable. You should use an appropriate List implementation if you need such behavior. If you want to access the elements by name, you can also use a Map.
Map<String, JSONObject> map = new HashMap<>();
for(int i = 0 ; i < 10 ; i++) {
map.put("tempName" + i, new JSONObject());
}
JSONObject o = map.get("tempName3"); // get the 4th created (hashmaps don't have an ordering though)
JSONArray arr = new JSONArray();
HashMap<String, JSONObject> map = new HashMap<String, JSONObject>();
for(int i = 0 ; i < 10 ; i++) {
JSONObject json=new JSONObject();
json.put("id",i);
json.put("firstName","abc"+i);
map.put("json" + i, json);
arr.put(map.get("json" + i));
}
System.println("The json string is " + arr.toString());
OutPut is
The json string is
[
{"id":0,"firstName":"abc0"},
{"id":1,"firstName":"abc1"},
{"id":2,"firstName":"abc2"},
{"id":3,"firstName":"abc3"},
{"id":4,"firstName":"abc4"}
]
Have you should try to use a framework like jackson Who will let unmarshall your json to real java object of your choice for example :
public class Data
{
private String blukiiId;
private String macAddress;
private String type;
...
private List<RSSI> rssi;
private BeaconSensorData beaconSensorData;
}
With Rssi,BeaconSensorData another class like that etc... Now your code will get Converted as below
public class getJSON
{
public static void main(String[] args) throws Exception{
ObjectMapper mapper = new ObjectMapper();
// Set any extra configs like ignore fields etc here
try{
Data data = mapper.convertValue(Files.readAllBytes(Paths.get("test.json"), Data.class);
//Now you can access the value as below
data.getBeaconSensorData().getEnvironment().getTemperature();
}catch(Exception e){
e.printStackTrace();
}
}
}
If you can only use org.json.simple.parser.JSONParser, please refer to the following java code by recursion.
import java.io.FileReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
public class getJSON
{
private static void visitElement(Object obj, Map<Object, Object> map) throws Exception {
if(obj instanceof JSONArray) {
JSONArray jsonArr = (JSONArray)obj;
Iterator<?> itr = jsonArr.iterator();
while(itr.hasNext())
visitElement(itr.next(), map);
}
else if(obj instanceof JSONObject) {
JSONObject jsonObj = (JSONObject)obj;
Iterator<?> itr = jsonObj.keySet().iterator();
while(itr.hasNext()) {
Object key = itr.next();
Object value = jsonObj.get(key);
map.put(key, value);
visitElement(value, map);
}
}
}
public static void main(String[] args) throws Exception{
JSONParser parser = new JSONParser();
try{
Object obj = parser.parse(new FileReader("C:/test.json"));
Map<Object, Object> map = new HashMap<>();
visitElement(obj, map);
for(Object key : map.keySet())
System.out.println(key + ": " + map.get(key));
}catch(Exception e){
e.printStackTrace();
}
}
}
If you want a new object with two keys, Object1 and Object2, you can do:
JSONObject Obj1 = (JSONObject) jso1.get("Object1");
JSONObject Obj2 = (JSONObject) jso2.get("Object2");
JSONObject combined = new JSONObject();
combined.put("Object1", Obj1);
combined.put("Object2", Obj2);
If you want to merge them, so e.g. a top level object has 5 keys (Stringkey1, ArrayKey, StringKey2, StringKey3, StringKey4), I think you have to do that manually:
JSONObject merged = new JSONObject(Obj1, JSONObject.getNames(Obj1));
for(String key : JSONObject.getNames(Obj2))
{
merged.put(key, Obj2.get(key));
}
This would be a lot easier if JSONObject implemented Map, and supported putAll.
In some cases you need a deep merge, i.e., merge the contents of fields with identical names (just like when copying folders in Windows). This function may be helpful:
/**
* Merge "source" into "target". If fields have equal name, merge them recursively.
* @return the merged object (target).
*/
public static JSONObject deepMerge(JSONObject source, JSONObject target) throws JSONException {
for (String key: JSONObject.getNames(source)) {
Object value = source.get(key);
if (!target.has(key)) {
// new value for "key":
target.put(key, value);
} else {
// existing value for "key" - recursively deep merge:
if (value instanceof JSONObject) {
JSONObject valueJson = (JSONObject)value;
deepMerge(valueJson, target.getJSONObject(key));
} else {
target.put(key, value);
}
}
}
return target;
}
/**
* demo program
*/
public static void main(String[] args) throws JSONException {
JSONObject a = new JSONObject("{offer: {issue1: value1}, accept: true}");
JSONObject b = new JSONObject("{offer: {issue2: value2}, reject: false}");
System.out.println(a+ " + " + b+" = "+JsonUtils.deepMerge(a,b));
// prints:
// {"accept":true,"offer":{"issue1":"value1"}} + {"reject":false,"offer":{"issue2":"value2"}} = {"reject":false,"accept":true,"offer":{"issue1":"value1","issue2":"value2"}}
}
I think the json string you provided should be like
"{\"bills\":[{\"amount\":\"13\",\"billId\":\"billid3\"} ,{\"amount\":\"155\",\"billId\":\"billid4\"}]}"
If this is the case, you can use the solution below:
Create two classes Bill.java and TestObject.java as follows:
Bill.java
public class Bill {
private double amount;
private String billId;
/**
* @return the amount
*/
public double getAmount() {
return amount;
}
/**
* @param amount the amount to set
*/
public void setAmount(double amount) {
this.amount = amount;
}
/**
* @return the billId
*/
public String getBillId() {
return billId;
}
/**
* @param billId the billId to set
*/
public void setBillId(String billId) {
this.billId = billId;
}
}
TestObject.java
import java.util.List;
public class TestObject {
private List<Bill> bills;
/**
* @return the bills
*/
public List<Bill> getBills() {
return bills;
}
/**
* @param bills the bills to set
*/
public void setBills(List<Bill> bills) {
this.bills = bills;
}
}
Here is the main program to test the code.
Test.java
import com.fasterxml.jackson.databind.ObjectMapper;
public class Test {
public static void main(String[] args) {
String jsonStr = "{\"bills\":[{\"amount\":\"13\",\"billId\":\"billid3\"} ,{\"amount\":\"155\",\"billId\":\"billid4\"}]}";
ObjectMapper mapper = new ObjectMapper();
try {
TestObject testObject = mapper.readValue(jsonStr, TestObject.class);
System.out.print(testObject);
} catch (Exception e) {
e.printStackTrace();
}
}
}
I have used gson-2.2.2.jar.
Please find code given below :
Bill.java
public class Bill
{
private double billAmount;
private String billId;
//getters and setters
}
Main.java
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class Main
{
public static void main(String[] args)
{
Bill bill = null;
List<Bill> bills = new ArrayList<Bill>();
for (int i = 0; i < 5; i++)
{
bill = new Bill();
bill.setBillAmount(100 + (i + 1));
bill.setBillId("bill_id_" + (i + 1));
bills.add(bill);
}
Gson gson = new Gson();
String json = gson.toJson(bills, new TypeToken<List<Bill>>()
{}.getType());
System.out.println(json);
Type mapType = new TypeToken<List<Bill>>()
{}.getType();
List<Bill> billsRetrieved = new Gson().fromJson(json, mapType);
for (Bill bill2 : billsRetrieved)
{
System.out.println(bill2.getBillId());
}
}
}
OutPut :
[
{
"billAmount":101.0,
"billId":"bill_id_1"
},
{
"billAmount":102.0,
"billId":"bill_id_2"
},
{
"billAmount":103.0,
"billId":"bill_id_3"
},
{
"billAmount":104.0,
"billId":"bill_id_4"
},
{
"billAmount":105.0,
"billId":"bill_id_5"
}
]
bill_id_1 bill_id_2 bill_id_3 bill_id_4 bill_id_5
Please revert in case you need further explanation.
I found very good link for JSON: http://code.google.com/p/json-simple/wiki/EncodingExamples#Example_1-1_-_Encode_a_JSON_object
Here's code to add multiple JSONObjects to JSONArray.
JSONArray Obj = new JSONArray();
try {
for(int i = 0; i < 3; i++) {
// 1st object
JSONObject list1 = new JSONObject();
list1.put("val1",i+1);
list1.put("val2",i+2);
list1.put("val3",i+3);
obj.put(list1);
}
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Toast.makeText(MainActivity.this, ""+obj, Toast.LENGTH_LONG).show();
Once you have put the values into the JSONObject then put the JSONObject into the JSONArray staright after.
Something like this maybe:
jsonObj.put("value1", 1);
jsonObj.put("value2", 900);
jsonObj.put("value3", 1368349);
jsonArray.put(jsonObj);
Then create new JSONObject, put the other values into it and add it to the JSONArray:
jsonObj.put("value1", 2);
jsonObj.put("value2", 1900);
jsonObj.put("value3", 136856);
jsonArray.put(jsonObj);
On the outermost level, a JSON object starts with a { and end with a }.
Sample data:
{
"cars": {
"Nissan": [
{"model":"Sentra", "doors":4},
{"model":"Maxima", "doors":4},
{"model":"Skyline", "doors":2}
],
"Ford": [
{"model":"Taurus", "doors":4},
{"model":"Escort", "doors":4}
]
}
}
If the JSON is assigned to a variable called data, then accessing it would be like the following:
data.cars['Nissan'][0].model // Sentra
data.cars['Nissan'][1].model // Maxima
data.cars['Nissan'][2].doors // 2
for (var make in data.cars) {
for (var i = 0; i < data.cars[make].length; i++) {
var model = data.cars[make][i].model;
var doors = data.cars[make][i].doors;
alert(make + ', ' + model + ', ' + doors);
}
}
Another approach (using an associative array for car models rather than an indexed array):
{
"cars": {
"Nissan": {
"Sentra": {"doors":4, "transmission":"automatic"},
"Maxima": {"doors":4, "transmission":"automatic"}
},
"Ford": {
"Taurus": {"doors":4, "transmission":"automatic"},
"Escort": {"doors":4, "transmission":"automatic"}
}
}
}
data.cars['Nissan']['Sentra'].doors // 4
data.cars['Nissan']['Maxima'].doors // 4
data.cars['Nissan']['Maxima'].transmission // automatic
for (var make in data.cars) {
for (var model in data.cars[make]) {
var doors = data.cars[make][model].doors;
alert(make + ', ' + model + ', ' + doors);
}
}
Edit:
Correction: A JSON object starts with { and ends with }, but it's also valid to have a JSON array (on the outermost level), that starts with [ and ends with ].
Also, significant syntax errors in the original JSON data have been corrected: All key names in a JSON object must be in double quotes, and all string values in a JSON object or a JSON array must be in double quotes as well.
See:
- JSON specification
- JSONLint - The JSON validator
A good book I'm reading: Professional JavaScript for Web Developers by Nicholas C. Zakas 3rd Edition has the following information regarding JSON Syntax:
"JSON Syntax allows the representation of three types of values".
Regarding the one you're interested in, Arrays it says:
"Arrays are represented in JSON using array literal notation from JavaScript. For example, this is an array in JavaScript:
var values = [25, "hi", true];
You can represent this same array in JSON using a similar syntax:
[25, "hi", true]
Note the absence of a variable or a semicolon. Arrays and objects can be used together to represent more complex collections of data, such as:
{
"books":
[
{
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
"edition": 3,
"year": 2011
},
{
"title": "Professional JavaScript",
"authors": [
"Nicholas C.Zakas"
],
"edition": 2,
"year": 2009
},
{
"title": "Professional Ajax",
"authors": [
"Nicholas C. Zakas",
"Jeremy McPeak",
"Joe Fawcett"
],
"edition": 2,
"year": 2008
}
]
}
This Array contains a number of objects representing books, Each object has several keys, one of which is "authors", which is another array. Objects and arrays are typically top-level parts of a JSON data structure (even though this is not required) and can be used to create a large number of data structures."
To serialize (convert) a JavaScript object into a JSON string you can use the JSON object stringify() method. For the example from Mark Linus answer:
var cars = [{
color: 'gray',
model: '1',
nOfDoors: 4
},
{
color: 'yellow',
model: '2',
nOfDoors: 4
}];
cars is now a JavaScript object. To convert it into a JSON object you could do:
var jsonCars = JSON.stringify(cars);
Which yields:
"[{"color":"gray","model":"1","nOfDoors":4},{"color":"yellow","model":"2","nOfDoors":4}]"
To do the opposite, convert a JSON object into a JavaScript object (this is called parsing), you would use the parse() method. Search for those terms if you need more information... or get the book, it has many examples.
Use this code and Enjoy :)
private void createJsonStructure() {
try
{
JSONObject rootObject = new JSONObject();
JSONArray carArr = new JSONArray();
for (int i = 0; i < 2 ; i++)
{
JSONObject jsonObject = new JSONObject();
jsonObject.put("CarId", "123");
jsonObject.put("Status", "Ok");
carArr.put(jsonObject);
}
rootObject.put("Car", carArr);
JSONArray motorArr = new JSONArray();
for (int i = 0; i < 2 ; i++)
{
JSONObject jsonObject = new JSONObject();
jsonObject.put("MotorId", "123");
jsonObject.put("Status", "Ok");
motorArr.put(jsonObject);
}
rootObject.put("Motor", motorArr);
JSONArray busArr = new JSONArray();
for (int i = 0; i < 2 ; i++)
{
JSONObject jsonObject = new JSONObject();
jsonObject.put("BusId", "123");
jsonObject.put("Status", "Ok");
busArr.put(jsonObject);
}
rootObject.put("Bus", busArr);
Log.e("JsonObject", rootObject.toString(4));
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
JSONObject motorObject = new JSONObject();
JSONObject busObject = new JSONObject();
JSONObject carObject = new JSONObject();
JSONObject wholeObject =new JSONObject();
JSONArray motorArray = new JSONArray();
JSONArray busArray = new JSONArray();
JSONArray carArray = new JSONArray();
motorArray.put(motorTracks.getJSONObject());
busArray.put(buss.getJSONObject());
carArray.put(car.getJSONObject());
try
{
wholeObject.put("Motor",motorArray);
wholeObject.put("Bus",busArray);
wholeObject.put("Car",carArray);
System.out.println(wholeObject);
}
catch (JSONException e)
{
e.printStackTrace();
}