How to parse below stream of Json objects?
There are example for array parsing but not stream of json objects. Only the first object is different other than that every other object is similar.
Its not array but stream of json objects.
[{
"code": 200,
"request_id": "52d868df5ada23e5f289320f",
"ok": true,
"payload_meta": {
"original_size": 1837,
"size": 1837
}
},{
"id": "4fb56d7f273fb7ebfe22783f",
"duration": "6:49",
"duration_seconds": 409,
"size_bytes": 16396948
}{
"id": "4fb56d7f273fb7ebfe227841",
"duration": "3:42",
"duration_seconds": 222,
"size_bytes": 8904980
}{
"id": "4fb56d7f273fb7ebfe227846",
"duration": "4:06",
"duration_seconds": 246,
"size_bytes": 9843339
}]
And also how to notify after parsing one object successfully instead of waiting whole stream to complete.
I made no assumptions on the kind of object you are trying to deserialize. So I named Class1 and Class2 the two kind of objects and they have no relationship. I declared them as inner static classes to make compat the example, but you can move Class1 and Class2 to separate files. I paste you a ready to run code so that you can try it on your own.
package stackoverflow.questions.q23556772;
import java.util.*;
import com.google.gson.*;
public class Q23556772 {
public static class Class1 {
String code;
String request_id;
Boolean ok;
HashMap<String, Integer> payload_meta;
#Override
public String toString() {
return "Class1 [code=" + code + ", request_id=" + request_id + ", ok=" + ok + ", payload_meta=" + payload_meta + "]";
}
}
public static class Class2 {
String id;
String duration;
Integer duration_seconds;
Integer size_bytes;
#Override
public String toString() {
return "Class2 [id=" + id + ", duration=" + duration + ", duration_seconds=" + duration_seconds + ", size_bytes=" + size_bytes + "]";
}
}
public static void main(String[] args) {
String json =
"[{ "+
" \"code\": 200, "+
" \"request_id\": \"52d868df5ada23e5f289320f\", "+
" \"ok\": true, "+
" \"payload_meta\": { "+
" \"original_size\": 1837, "+
" \"size\": 1837 "+
" } "+
"},{ "+
" \"id\": \"4fb56d7f273fb7ebfe22783f\", "+
" \"duration\": \"6:49\", "+
" \"duration_seconds\": 409, "+
" \"size_bytes\": 16396948 "+
"},{ "+
" \"id\": \"4fb56d7f273fb7ebfe227841\", "+
" \"duration\": \"3:42\", "+
" \"duration_seconds\": 222, "+
" \"size_bytes\": 8904980 "+
"},{ "+
" \"id\": \"4fb56d7f273fb7ebfe227846\", "+
" \"duration\": \"4:06\", "+
" \"duration_seconds\": 246, "+
" \"size_bytes\": 9843339 "+
"}] ";
ArrayList<Object> result = new ArrayList<>();
Gson g = new Gson();
JsonArray e = new JsonParser().parse(json).getAsJsonArray();
for(int i = 0; i < e.size(); i++){
JsonObject o = e.get(i).getAsJsonObject();
if (o.get("code") != null)
result.add(g.fromJson(o, Class1.class));
else if (o.get("id") != null)
result.add(g.fromJson(o, Class2.class));
else result.add(g.fromJson(o, Object.class));
}
for(Object resultObject: result)
System.out.println(resultObject.toString());
}
}
As you can see, I use a combination of JsonParser and Gson methods. I use the parser to peek inside the "stream" and to decide what is the correct class to use, then I use standard Gson deserialization to do the work. This code could be adapted into a custom TypeAdapter, but probably it makes the code "complex" beyond your real needs.
Final note: I edited your JSON since it was incorrect.
Related
This question already has answers here:
How to parse JSON in Java
(36 answers)
How to read all keys in Json without specifying keyname using java
(2 answers)
Closed 1 year ago.
I would like to read the data from the JSON file, but not only the values but also the fields in this file, i.e. "_id", "name", "surname" etc. For example, I have a file like the one below and the problem is that the files will contain different data and it is not one and the same the file itself so the fields will change and not be the same all the time.
[
{
"_id": 1,
"name": "Adam",
"surname": "Smith",
"course": "IT",
"grades": [
{
"maths": 4,
"physics": 4,
"programming": 5
},
{
"maths": 3,
"physics": 5,
"programming": 4
}
]
},
{
"_id": 2,
"name": "Robert",
"surname": "Brown",
"course": "IT",
"grades": [
{
"maths": 5,
"physics": 5,
"angielski": 5
},
{
"maths": 4,
"physics": 4,
"programming": 4
}
]
}
]
I thought about parsing the file into a string and reading it character by character, but that would be time consuming. And here is my question, how to read not only values but also fields in a JSON file.
I think you want to iterate over all Objects/Arrays in this json.
If you are fine using a library, below one will be helpful
Maven:
<dependency>
<groupId>org.json</groupId>
<artifactId>org.json</artifactId>
<version>chargebee-1.0</version>
</dependency>
This is a sample code for reading your string
import java.io.IOException;
import java.util.Iterator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Test {
public static void main(String[] args) throws IOException, JSONException {
String json_str = "[{\r\n" +
" \"_id\": 1,\r\n" +
" \"name\": \"Adam\",\r\n" +
" \"surname\": \"Smith\",\r\n" +
" \"course\": \"IT\",\r\n" +
" \"grades\": [\r\n" +
" {\r\n" +
" \"maths\": 4,\r\n" +
" \"physics\": 4,\r\n" +
" \"programming\": 5\r\n" +
" },\r\n" +
" {\r\n" +
" \"maths\": 3,\r\n" +
" \"physics\": 5,\r\n" +
" \"programming\": 4\r\n" +
" }]\r\n" +
" },{\r\n" +
" \"_id\": 2,\r\n" +
" \"name\": \"Robert\",\r\n" +
" \"surname\": \"Brown\",\r\n" +
" \"course\": \"IT\",\r\n" +
" \"grades\": [\r\n" +
" {\r\n" +
" \"maths\": 5,\r\n" +
" \"physics\": 5,\r\n" +
" \"angielski\": 5\r\n" +
" },\r\n" +
" {\r\n" +
" \"maths\": 4,\r\n" +
" \"physics\": 4,\r\n" +
" \"programming\": 4\r\n" +
" }]\r\n" +
"}]";
JSONArray jsonArray = new JSONArray(json_str);
int length = jsonArray.length();
for(int i=0; i<length; i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Iterator<String> keys = jsonObject.keys();
while(keys.hasNext()) {
//this will give 1st level keys - "surname,name,course,_id,grades"
String key = keys.next();
if (jsonObject.get(key) instanceof JSONObject) {
//build either a recursive function or required logic to iterate over inner json objects similar to this
} else if (jsonObject.get(key) instanceof JSONArray) {
//build either a recursive function or required logic to iterate over inner json arrays similar to this
} else {
/* Output:
key is = surname ==> value is = Smith
key is = name ==> value is = Adam
key is = course ==> value is = IT
key is = _id ==> value is = 1
key is = surname ==> value is = Brown
key is = name ==> value is = Robert
key is = course ==> value is = IT
key is = _id ==> value is = 2
*/
System.out.println("key is = "+key+" ==> value is = "+jsonObject.get(key));
}
}
}
}
}
I've a JSON:
{
"payment_intent": {
"amount": "Amount",
"currency_code": "840",
"invoice_number": "pay-automation-invoice-no-01",
"payment_intent_id": "pay-automation-return-intent-id-01",
"intent_reference_id": "pay-automation-intent-reference-id-01"
},
"payment_refundable_intents": {
"transactions": {
"sales": "pay-automation-sales"
}
}
}
Now, when I tried to replace string "pay-automation-sales" with JSONArray using
payloadJson = payloadJson.replaceAll("pay-automation-sales", salesString);
salesString is
[{"amount":"200.0","payment_intent_id":"29518150","tender_type":"cash","reference_id":"db79893a-9fe0-4391-91f8-fbc-cash-6c88-66db","intent_reference_id":"db79893a-9fe0-4391-91f8-fbc7945ce446","id":"000000893275","status":"Approved"},{"amount":"800.0","payment_intent_id":"29518150","tender_type":"cash","reference_id":"db79893a-9fe0-4391-91f8-fbc-cash-1d12-8466","intent_reference_id":"db79893a-9fe0-4391-91f8-fbc7945ce446","id":"000000893282","status":"Approved"}]
Here, payloadJson is of type String. The replaceAll works fine but actually I want to pass "sales" as an array of object in JSON. But it is getting passed like this and it's not a valid JSON format. Double quotes in value of sales key in JSON causes an issue I think.
"sales": "[{"amount":"200.0","payment_intent_id":"29518150","tender_type":"cash","reference_id":"db79893a-9fe0-4391-91f8-fbc-cash-6c88-66db","intent_reference_id":"db79893a-9fe0-4391-91f8-fbc7945ce446","id":"000000893275","status":"Approved"},{"amount":"800.0","payment_intent_id":"29518150","tender_type":"cash","reference_id":"db79893a-9fe0-4391-91f8-fbc-cash-1d12-8466","intent_reference_id":"db79893a-9fe0-4391-91f8-fbc7945ce446","id":"000000893282","status":"Approved"}]"
How do I replace string in JSON with valid JSON array of objects?
Since you're working with String objects here and not some form of JSON object model, when you did
payloadJson = payloadJson.replaceAll("pay-automation-sales", salesString);
it found the string
pay-automation-sales
within payloadJson and replaced it verbatin with the contents of salesString. Notice that you did NOT tell it to include the quotes in the original string in the part being replaced.
It should be
payloadJson = payloadJson.replaceAll("\"pay-automation-sales\"", salesString);
You would probably be better off using a real JSON library that understands JSON syntax and can manipulate the JSON as an in-memory document model.
Using Java String
public class StringDemo {
static final String originalJson = " {\n"
+ " \"payment_intent\": {\n"
+ " \"amount\": \"Amount\",\n"
+ " \"currency_code\": \"840\",\n"
+ " \"invoice_number\": \"pay-automation-invoice-no-01\",\n"
+ " \"payment_intent_id\": \"pay-automation-return-intent-id-01\",\n"
+ " \"intent_reference_id\": \"pay-automation-intent-reference-id-01\"\n"
+ " },\n"
+ " \"payment_refundable_intents\": {\n"
+ " \"transactions\": {\n"
+ " \"sales\": \"pay-automation-sales\"\n"
+ " }\n"
+ " }\n"
+ "}";
static final String originalArray = "[{\"amount\":\"200.0\",\"payment_intent_id\":\"29518150\",\"tender_type\":\"cash\",\"reference_id\":\"db79893a-9fe0-4391-91f8-fbc-cash-6c88-66db\",\"intent_reference_id\":\"db79893a-9fe0-4391-91f8-fbc7945ce446\",\"id\":\"000000893275\",\"status\":\"Approved\"},{\"amount\":\"800.0\",\"payment_intent_id\":\"29518150\",\"tender_type\":\"cash\",\"reference_id\":\"db79893a-9fe0-4391-91f8-fbc-cash-1d12-8466\",\"intent_reference_id\":\"db79893a-9fe0-4391-91f8-fbc7945ce446\",\"id\":\"000000893282\",\"status\":\"Approved\"}]";
public static void main(String[] args) {
String editedJson = originalJson.replaceAll("\"pay-automation-sales\"", originalArray);
System.out.println(editedJson);;
}
}
Using Jackson
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.node.*;
public class JacksonDemo {
static final String originalJson = " {\n"
+ " \"payment_intent\": {\n"
+ " \"amount\": \"Amount\",\n"
+ " \"currency_code\": \"840\",\n"
+ " \"invoice_number\": \"pay-automation-invoice-no-01\",\n"
+ " \"payment_intent_id\": \"pay-automation-return-intent-id-01\",\n"
+ " \"intent_reference_id\": \"pay-automation-intent-reference-id-01\"\n"
+ " },\n"
+ " \"payment_refundable_intents\": {\n"
+ " \"transactions\": {\n"
+ " \"sales\": \"pay-automation-sales\"\n"
+ " }\n"
+ " }\n"
+ "}";
static final String originalArray = "[{\"amount\":\"200.0\",\"payment_intent_id\":\"29518150\",\"tender_type\":\"cash\",\"reference_id\":\"db79893a-9fe0-4391-91f8-fbc-cash-6c88-66db\",\"intent_reference_id\":\"db79893a-9fe0-4391-91f8-fbc7945ce446\",\"id\":\"000000893275\",\"status\":\"Approved\"},{\"amount\":\"800.0\",\"payment_intent_id\":\"29518150\",\"tender_type\":\"cash\",\"reference_id\":\"db79893a-9fe0-4391-91f8-fbc-cash-1d12-8466\",\"intent_reference_id\":\"db79893a-9fe0-4391-91f8-fbc7945ce446\",\"id\":\"000000893282\",\"status\":\"Approved\"}]";
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(originalJson);
JsonNode array = mapper.readTree(originalArray);
ObjectNode transactions = (ObjectNode) root.findValue("transactions");
transactions.set("sales", array);
String editedJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root);
System.out.println(editedJson);;
}
}
I need help in mapping below JSON structure for further processing.
[{
"userId": "11",
"otherId": "a",
"key1": "Tesla",
"key2": "S3",
"behaviour": {
"color": "white",
"size": "S",
"owner": "Mr. A"
}
},
{
"userId": "22",
"otherId": "",
"key1": "Merc",
"key2": "C-Class",
"behaviour": {
"color": "black",
"size": "M",
"isNew": true
}
},
{
"userId": "33",
"otherId": "c",
"key1": "Honda",
"key2": "CRV",
"behaviour": {
"color": "green",
"size": "L",
}
}]
Below is the POJO i have:
public class MainObject {
private String userId;
private String otherId;
private String key1;
private String key2;
private Set<Behaviour> behaviours;
}
public class Behaviour {
private final String name;
private final Object value;
}
I need to get the list of MainObject for further processing. Tried below but not sure how can i map for behaviour set -
String inputLine = currentBufferedReader.readLine();
//Above String has complete JSON
ObjectMapper objectMapper = new ObjectMapper();
FirstObject[] firstObjects = objectMapper.readValue(inputLine, FirstObject[].class);
I am getting: Unrecognized field not marked as ignorable with above code. Please suggest.
Define ur class like belwo
class MainObject {
public String userId;
public String otherId;
public String key1;
public String key2;
#JsonProperty(value = "behaviour")
public Map<String, String> behaviours;
#Override
public String toString() {
return "MainObject [userId=" + userId + ", otherId=" + otherId + ", key1=" + key1 + ", key2=" + key2
+ ", behaviours=" + behaviours + "]";
}
}
Code to map
public static void main(String[] args) throws IOException {
String array = "[\r\n" +
" {\r\n" +
" \"userId\":\"11\",\r\n" +
" \"otherId\":\"a\",\r\n" +
" \"key1\":\"Tesla\",\r\n" +
" \"key2\":\"S3\",\r\n" +
" \"behaviour\":{\r\n" +
" \"color\":\"white\",\r\n" +
" \"size\":\"S\",\r\n" +
" \"owner\":\"Mr. A\"\r\n" +
" }\r\n" +
" },\r\n" +
" {\r\n" +
" \"userId\":\"22\",\r\n" +
" \"otherId\":\"\",\r\n" +
" \"key1\":\"Merc\",\r\n" +
" \"key2\":\"C-Class\",\r\n" +
" \"behaviour\":{\r\n" +
" \"color\":\"black\",\r\n" +
" \"size\":\"M\",\r\n" +
" \"isNew\":true\r\n" +
" }\r\n" +
" },\r\n" +
" {\r\n" +
" \"userId\":\"33\",\r\n" +
" \"otherId\":\"c\",\r\n" +
" \"key1\":\"Honda\",\r\n" +
" \"key2\":\"CRV\",\r\n" +
" \"behaviour\":{\r\n" +
" \"color\":\"green\",\r\n" +
" \"size\":\"L\"\r\n" +
" }\r\n" +
" }\r\n" +
"]";
ObjectMapper mapper = new ObjectMapper();
MainObject[] objects = mapper.readValue(array, MainObject[].class);
System.out.println(Arrays.asList(objects));
}
output
[MainObject [userId=11, otherId=a, key1=Tesla, key2=S3, behaviours={color=white, size=S, owner=Mr. A}],
MainObject [userId=22, otherId=, key1=Merc, key2=C-Class, behaviours={color=black, size=M, isNew=true}],
MainObject [userId=33, otherId=c, key1=Honda, key2=CRV, behaviours={color=green, size=L}]]
I have JSON string that needs to be converted in Java object using Google Gson library.
I am stuck in converting due to forward slash in the following JSON string.
{
"status":"200",
"results":{
"resultitems":[
{
"uri":"/document/id/e20a8dad50d91a839c50ab5f323f3df3",
"path":"Data/xyz/abcdata",
"metadata":{
"data/category/item":"yahoo/post",
"ast_id":"67677"
}
}
]
}
Indeed, for Data/category/item, I am getting a null value. How can I correctly parse it?
Just a starting note: the JSON you put in request is not a valid JSON, but can be easily fixed adding a brace (I used fixed JSON in my answer).
I suggest you to parse your JSON this way. Declare the following classes.
public class Container {
public int status;
public Results results;
#Override
public String toString() {
return "Container [status=" + status + ", results=" + results + "]";
}
}
public class Results {
public List<ResultItem> resultitems;
#Override
public String toString() {
return "Results [resultitems=" + resultitems + "]";
}
}
public class ResultItem {
String uri;
String path;
HashMap metadata;
#Override
public String toString() {
return "ResultItem [uri=" + uri + ", path=" + path + ", metadata="
+ metadata + "]";
}
}
and then call this code:
public class Q19684865 {
public static void main(String[] args) {
String json = " { "
+ " \"status\":\"200\", "
+ " \"results\":{ "
+ " \"resultitems\":[ "
+ " { "
+ " \"uri\":\"/document/id/e20a8dad50d91a839c50ab5f323f3df3\", "
+ " \"path\":\"Data/xyz/abcdata\", "
+ " \"metadata\":{ "
+ " \"data/category/item\":\"yahoo/post\", "
+ " \"ast_id\":\"67677\" "
+ " } "
+ " } "
+ " ] "
+ " } "
+ " } ";
Container c = new Gson().fromJson(json, Container.class);
System.out.println("this is the parsed json: " +c);
System.out.println("this is the property 'data/category/item': "+c.results.resultitems.get(0).metadata.get("data/category/item"));
}
and this is the result:
this is the parsed json: Container [status=200, results=Results [resultitems=[ResultItem [uri=/document/id/e20a8dad50d91a839c50ab5f323f3df3, path=Data/xyz/abcdata, metadata={data/category/item=yahoo/post, ast_id=67677}]]]]
this is the property 'data/category/item': yahoo/post
Explanation: normally you need just POJOs if you do not have particular needs, where POJO field name corresponds to the label of the JSON value. But 'data/category/item' cannot be a valid Java identifier. So I chose to parse to a Map.
A second way could be to replace in JSON string your "data/category/item" with a valid Java identifier, "data_category_item" for example or, if you can change JSON origin, do the same at the source.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have following JSON structure from a web service:
{
"owner": {
"username": "bobby",
"password": "$2a$10$KTouvpAZwyUiCOsvMej.i.zNcGVt94d.n64MHWyxX35ZR03tWCIui",
"email": "bobby#email.com",
"name": "Bobby P",
"_id": "51a59d917997582c3a000003",
"__v": 0,
"phones": [
"11118012888",
"12341234",
"987655775"
],
"altemails": [
"a#a.com",
"b#b.com",
"c#c.com"
]
},
"facilities": [
{
"url": "/v1/facilities/51a5a6237997582c3a000006"
},
{
"url": "/v1/facilities/51a5a6237997582c3a000007"
},
{
"url": "/v1/facilities/51a5b533ebcefa893d000003"
},
{
"url": "/v1/facilities/51b0238edadae8024f000003"
}
]
}
for this JSON response. I need only the facilities array.
Can anyone please tell me how to write a Bean class so that I can read it using Gson in Android?
You need this:
package stackoverflow.questions.q18943680;
import java.util.ArrayList;
public class Owner {
String username;
String password;
String email;
String name;
String _id;
int __v;
ArrayList<String> phones;
#Override
public String toString() {
return "Owner [username=" + username + ", password=" + password
+ ", email=" + email + ", name=" + name + ", _id=" + _id
+ ", __v=" + __v + ", phones=" + phones + "]";
}
}
this:
package stackoverflow.questions.q18943680;
public class Facility {
String url;
#Override
public String toString() {
return "Facility [url=" + url + "]";
}
}
and this:
package stackoverflow.questions.q18943680;
import java.util.ArrayList;
public class TestBean {
public Owner owner;
public ArrayList<Facility> facilities;
#Override
public String toString() {
return "TestBean [owner=" + owner + ", facilities=" + facilities + "]";
}
}
and you will get your result with:
package stackoverflow.questions.q18943680;
import com.google.gson.Gson;
public class Q18943680 {
/**
* #param args
*/
public static void main(String[] args) {
String json = "{"+
" \"owner\": { "+
" \"username\": \"bobby\", "+
" \"password\": \"$2a$10$KTouvpAZwyUiCOsvMej.i.zNcGVt94d.n64MHWyxX35ZR03tWCIui\", "+
" \"email\": \"bobby#email.com\", "+
" \"name\": \"Bobby P\", "+
" \"_id\": \"51a59d917997582c3a000003\", "+
" \"__v\": 0, "+
" "+
" \"phones\": [ "+
" \"11118012888\", "+
" \"12341234\", "+
" \"987655775\" "+
" "+
" ], "+
" \"altemails\": [ "+
" \"a#a.com\", "+
" \"b#b.com\", "+
" \"c#c.com\" "+
" ] "+
" "+
"}, "+
" "+
"\"facilities\": [ "+
" { "+
" \"url\": \"/v1/facilities/51a5a6237997582c3a000006\" "+
" }, "+
" { "+
" \"url\": \"/v1/facilities/51a5a6237997582c3a000007\" "+
" }, "+
" { "+
" \"url\": \"/v1/facilities/51a5b533ebcefa893d000003\" "+
" }, "+
" { "+
" \"url\": \"/v1/facilities/51b0238edadae8024f000003\" "+
" } "+
"]} ";
Gson g = new Gson();
TestBean tb = g.fromJson(json, TestBean.class);
System.out.println("This is the result: "+tb.facilities);
}
}
That gives you:
This is the result: [Facility [url=/v1/facilities/51a5a6237997582c3a000006], Facility [url=/v1/facilities/51a5a6237997582c3a000007], Facility [url=/v1/facilities/51a5b533ebcefa893d000003], Facility [url=/v1/facilities/51b0238edadae8024f000003]]
I suggest you using http://json.parser.online.fr/ to quickly parse your JSON to get a visual description on how things are arranged into your JSON for building other beans.