Trouble parsing long in JSON - java

I posted here earlier and was flagged for my post being too similar to another previously answered. I don't believe this is, so have tried to reword it.
I have a JSON file where value is either a long, or can contain an object and a array:
{
"declaration-list" : [
{
"declared-variable" : "x301",
"value" : {
"operator" : "set",
"arguments" : [
0,
1
]
}
},
{
"declared-variable" : "x112",
"value" : -1
},
]
}
I have written the following code in java to parse the file and have managed to extract declared-variable from the array (Note: I'm using org.json.simple):
public static void getInput() throws IOException, ParseException {
JSONParser parser = new JSONParser();
File file = new File("myfile");
Object object = parser.parse(new FileReader(file));
JSONObject jsonObject = (JSONObject) object;
JSONArray jasonArray = (JSONArray) jsonObject.get("declaration-list");
for (Object JSI : jasonArray) {
if (JSI instanceof JSONObject) {
JSONObject declared_variable = (JSONObject) JSI;
String decVar = (String) declared_variable.get("declared-variable");
System.out.println(decVar);
JSONObject value = (JSONObject) JSI;
String operator = (String) value.get("operator");
System.out.println(operator);
}
}
}
How do I get a long from a JSONArray and deal with the case where value contains another JSONObject and JSONArray?
I hope this post is more clear, thanks.

It seems you are using the dependency (the version may differ):
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
The appropriate value type interpretation (i.e. handling the value corresponding to its type) should be implemented.
Consider the following draft example. Take a look at the implementation of the handleDeclaredVariable method to get the basic understanding: it should answer your questions.
Update the loop:
for (final Object JSI : jasonArray) {
if (JSI instanceof JSONObject) {
handleDeclaredVariable((JSONObject) JSI);
}
}
Introduce the method:
private static void handleDeclaredVariable(final JSONObject variable) {
final String variableName = (String) variable.get("declared-variable");
final Object value = variable.get("value");
if (value instanceof JSONObject) {
final JSONObject jsonValue = (JSONObject) value;
final String operator = (String) jsonValue.get("operator");
final JSONArray arguments = (JSONArray) jsonValue.get("arguments");
System.out.println(
String.format(
"The value of the variable %s is a JSON object: operator: %s, arguments: %s",
variableName,
operator,
arguments
)
);
} else if (value instanceof Number) {
final Number numberValue = (Number) value;
System.out.println(
String.format(
"The value of the variable %s is a Number: %s",
variableName,
numberValue
)
);
} else {
System.err.println(
String.format(
"The value of the variable %s has unsupported type (%s): %s",
variableName,
value.getClass().getCanonicalName(),
value
)
);
}
}

Related

Json.simple returns null when I try to get my JSON Values even if I have a value in my JSON

public static void smth()
throws ParseException, FileNotFoundException, IOException, InterruptedException {
JSONParser parser = new JSONParser();
FileReader reader = new FileReader("release.json");
Object obj = parser.parse(reader); // Parse JSON data of file
JSONObject json = (JSONObject) obj;
String version = (String) json.get("version");
String license = (String) json.get("license");
String licenseFile = (String) json.get("LICENSE.txt?");
String date = (String) json.get("date");
String author = (String) json.get("author");
String contrib = (String) json.get("contributors");
String lib = (String) json.get("libraries");
String[] values = { version, license, author, contrib, date, lib, licenseFile };
for (int i = 0; i < values.length; i++) {
System.out.println(values[i]);
}
}
JSON.simple returns null, why? My JSON does have a keys corresponding to the json.get("key");.
I followed a tutorial and my tree is similar to the tutorial's code. I have printed one of them just to debug, when printing the array values, it just prints out null for every json.get("key"); statment
My JSON:
{
"release": {
"version": "0.0.1 InDev",
"license": "GNU General Public License v3",
"LICENSE.txt?" : "Webber/LICENSE.txt",
"date" : "18th Februaru, 2022 # 4:59PM Indian Standard Time",
"author" : "Habis Muhammed",
"contributors" : "***** 🙁 Nobody *****",
"libraries":"json-simple"
}
}
JSONObject json = (JSONObject) obj;
json = (JSONObject) json.get("release");
String version = (String) json.get("version");
You can try this.
You have to traverse from JSON object root

How to iterrate through Json Array and return each value

I have a Json file that contains an Array of Json Objects:
[{"id":"939f0080-e93e-4245-80d3-3ac58a4a4335","name":"Micha","date":"2021-04-20T11:21:48.000Z","entry":"Wow"}, {"id":"939f0070-e93f-4235-80d3-3ac58a4a4324","name":"Sarah","date":"2021-04-21T11:21:48.000Z","entry":"Hi"}, {"id":"897f0080-e93e-4235-80d3-3ac58a4a4324","name":"John","date":"2021-04-25T17:11:48.000Z","entry":"Hi how are you"}...]
I'm using Json-simple to get the array, but I'm only able to get the object, but not the values.
JSONParser jsonParser = new JSONParser();
try {
FileReader reader = new FileReader("j.json");
Object object = jsonParser.parse(reader);
JSONArray jsonArray = (JSONArray) object;
//prints the first Object
System.out.println("element 1 is" + jsonArray.get(0));
//prints whole Array
System.out.println(jsonArray);
how do i Iterate trough my file and get the values of each date, name date and entry instead of the object?
I want to get something like :
"id is 939f0080-e93e-4245-80d3-3ac58a4a4335 name is Micha date is 2021-04-20T11:21:48.000Z enry is wow"
"id is 939f0070-e93f-4235-80d3-3ac58a4a4324 name is Sarah 2021-04-21T11:21:48.000Z date is 2021-04-21T11:21:48.000Z"
"name is ..."
What you want is basically this
public static void main(String[] args) {
JSONParser jsonParser = new JSONParser();
try (FileReader reader = new FileReader("j.json")) {
Object object = jsonParser.parse(reader);
JSONArray jsonArray = (JSONArray) object;
for (Object o : jsonArray) {
JSONObject jsonObject = (JSONObject) o;
System.out.printf("id is %s name is %s date is %s entry is %s%n", jsonObject.get("id"), jsonObject.get("name"), jsonObject.get("date"), jsonObject.get("entry"));
// Or if you want all
for (Object key : jsonObject.keySet()) {
System.out.printf("%s is %s", key, jsonObject.get(key));
}
System.out.println();
}
} catch (IOException | ParseException e) {
e.printStackTrace();
}
}
You can use getOrDefault in case the attribute is optional. There are also countless other libraries which can transform your json into a java object. This will give you more type safety. E.g. jackson or gson.
JSONArray implements Collection and Iterable, so you can iterate over it with a For loop or using an Iterator or Stream. sadly, the object is not generic typed, so you will always get Objects and have to cast them yourself:
for(Object value : jsonArray) {
// your code here //
}
Hope this helps:
JSONParser jsonParser = new JSONParser();
try {
Object object = jsonParser.parse("[{\"id\":\"939f0080-e93e-4245-80d3-3ac58a4a4335\",\"name\":\"Micha\",\"date\":\"2021-04-20T11:21:48.000Z\",\"entry\":\"Wow\"}, {\"id\":\"939f0070-e93f-4235-80d3-3ac58a4a4324\",\"name\":\"Sarah\",\"date\":\"2021-04-21T11:21:48.000Z\",\"entry\":\"Hi\"}, {\"id\":\"897f0080-e93e-4235-80d3-3ac58a4a4324\",\"name\":\"John\",\"date\":\"2021-04-25T17:11:48.000Z\",\"entry\":\"Hi how are you\"}]");
JSONArray jsonArray = (JSONArray) object;
jsonArray.forEach(x -> {
JSONObject o = (JSONObject) x;
String collect = o.entrySet()
.stream()
.map(e -> e.getKey() + " is " + e.getValue().toString())
.collect(Collectors.joining(" "));
System.out.println(collect);
});
} catch (ParseException e) {
e.printStackTrace();
}

How I can get "name" under the "language" attribute of this JSONArray?

I use a Web-API for a Android App. But I have a problem to get "name" from the attribute "languages".
For the "name" of country I used:
protected String parseJSON(String jsonString) throws Exception {
if (jsonString == null || jsonString.trim().length() == 0) {
return "empty Object";
}
JSONArray jsonarray = new JSONArray(jsonString);
JSONObject jsonObject = jsonarray.getJSONObject(0);
String name = jsonObject.getString("name");
return name;
}
How I can get "name" under the "language" attribute of this JSONArray?
https://restcountries.eu/rest/v2/name/spain
It should be something like this:
JSONArray languages = jsonObject.getJSONArray("languages");
String firstLanguageName = languages.getJSONObject(0).getString("name");
Even though I strongly encourage you using gson instead of parsing this way, gson makes life easier when parsing json.
I use this maven dependency for parsing JSON: https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple
Using that, the method you are looking for would be:
protected String parseJSON(String jsonString) throws Exception {
if (jsonString == null || jsonString.trim().length() == 0) {
return "empty Object";
}
JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) ((JSONArray) parser.parse(jsonString)).get(0);
JSONObject language = (JSONObject) ((JSONArray) jsonObject.get("languages")).get(0);
return (String) language.get("name");
}
Assuming that you only care about the first language in that json, as the "languages" object is an array.

How do I get a list of all JSON paths to values from a JSON String?

My goal is to read a JSON file and understand the location of all the values, so that when I encounter that same JSON, I can easily read all the values. I am looking for a way to return a list containing all of the paths to each data value, in Jayway JsonPath format.
Example JSON:
{
"shopper": {
"Id": "4973860941232342",
"Context": {
"CollapseOrderItems": false,
"IsTest": false
}
},
"SelfIdentifiersData": {
"SelfIdentifierData": [
{
"SelfIdentifierType": {
"SelfIdentifierType": "111"
}
},
{
"SelfIdentifierType": {
"SelfIdentifierType": "2222"
}
}
]
}
}
Ideally I would like to take that JSON as a String and do something like this:
String json = "{'shopper': {'Id': '4973860941232342', 'Context': {'CollapseOrderItems': false, 'IsTest': false } }, 'SelfIdentifiersData': {'SelfIdentifierData': [{'SelfIdentifierType': {'SelfIdentifierType': '111'} }, {'SelfIdentifierType': {'SelfIdentifierType': '2222'} } ] } }";
Configuration conf = Configuration.defaultConfiguration();
List<String> jsonPaths = JsonPath.using(conf).parse(json).read("$");
for (String path : jsonPaths) {
System.out.println(path);
}
This code would print this, which is the location of all values in the JSON:
$.shopper.Id
$.shopper.Context.CollapseOrderItems
$.shopper.Context.IsTest
$.SelfIdentifiersData[0].SelfIdentifierData.SelfIdentifierType.SelfIdentifierType
$.SelfIdentifiersData[1].SelfIdentifierData.SelfIdentifierType.SelfIdentifierType
Then ideally, I would be able to take that list and parse the same JSON object to get each value present.
//after list is created
Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
for (String path : jsonPaths) {
Object value = JsonPath.read(document, path);
//do something
}
I am aware that I could get a Map that is a representation of the JSON file, but I am not sure that provides the same ease of access to retrieve all the values. If there is a easy way to do with JSONPath, that would be great, otherwise any other approaches are welcome.
I came up with a solution, sharing in case anyone else is looking for the same thing:
public class JsonParser {
private List<String> pathList;
private String json;
public JsonParser(String json) {
this.json = json;
this.pathList = new ArrayList<String>();
setJsonPaths(json);
}
public List<String> getPathList() {
return this.pathList;
}
private void setJsonPaths(String json) {
this.pathList = new ArrayList<String>();
JSONObject object = new JSONObject(json);
String jsonPath = "$";
if(json != JSONObject.NULL) {
readObject(object, jsonPath);
}
}
private void readObject(JSONObject object, String jsonPath) {
Iterator<String> keysItr = object.keys();
String parentPath = jsonPath;
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.get(key);
jsonPath = parentPath + "." + key;
if(value instanceof JSONArray) {
readArray((JSONArray) value, jsonPath);
}
else if(value instanceof JSONObject) {
readObject((JSONObject) value, jsonPath);
} else { // is a value
this.pathList.add(jsonPath);
}
}
}
private void readArray(JSONArray array, String jsonPath) {
String parentPath = jsonPath;
for(int i = 0; i < array.length(); i++) {
Object value = array.get(i);
jsonPath = parentPath + "[" + i + "]";
if(value instanceof JSONArray) {
readArray((JSONArray) value, jsonPath);
} else if(value instanceof JSONObject) {
readObject((JSONObject) value, jsonPath);
} else { // is a value
this.pathList.add(jsonPath);
}
}
}
}
Refer to this utility : https://github.com/wnameless/json-flattener
Perfect answer to your requirement. Provides Flattened map and Flattened strings for complex json strings.
I am not the author of this but have used it successfully for my usecase.

How do I parse JSON into an int?

I have Parsed some JSON data and its working fine as long as I store it in String variables.
My problem is that I need the ID in an int varibable and not in String.
i have tried to make a cast int id = (int) jsonObj.get("");
But it gives an error message that I cannot convert an object to an int.
So I tried to convert by using:
String id = (String) jsonObj.get("id");
int value = Integer.parseInt(id);
But also that is not working. What is wrong. How is JSON working with int?
My strings are working just fine its only when I try to make them as an int I get problems.
Here is my code :
public void parseJsonData() throws ParseException {
JSONParser parser = new JSONParser();
Object obj = parser.parse(jsonData);
JSONObject topObject = (JSONObject) obj;
JSONObject locationList = (JSONObject) topObject.get("LocationList");
JSONArray array = (JSONArray) locationList.get("StopLocation");
Iterator<JSONObject> iterator = array.iterator();
while (iterator.hasNext()) {
JSONObject jsonObj = (JSONObject) iterator.next();
String name =(String) jsonObj.get("name");
String id = (String) jsonObj.get("id");
Planner.getPlanner().setLocationName(name);
Planner.getPlanner().setArrayID(id);
}
}
You may use parseInt :
int id = Integer.parseInt(jsonObj.get("id"));
or better and more directly the getInt method :
int id = jsonObj.getInt("id");
It depends on the property type that you are parsing.
If the json property is a number (e.g. 5) you can cast to Long directly, so you could do:
(long) jsonObj.get("id") // with id = 5, cast `5` to long
After getting the long,you could cast again to int, resulting in:
(int) (long) jsonObj.get("id")
If the json property is a number with quotes (e.g. "5"), is is considered a string, and you need to do something similar to Integer.parseInt() or Long.parseLong();
Integer.parseInt(jsonObj.get("id")) // with id = "5", convert "5" to Long
The only issue is, if you sometimes receive id's a string or as a number (you cant predict your client's format or it does it interchangeably), you might get an exception, especially if you use parseInt/Long on a null json object.
If not using Java Generics, the best way to deal with these runtime exceptions that I use is:
if(jsonObj.get("id") == null) {
// do something here
}
int id;
try{
id = Integer.parseInt(jsonObj.get("id").toString());
} catch(NumberFormatException e) {
// handle here
}
You could also remove that first if and add the exception to the catch.
Hope this helps.
Its very simple.
Example JSON:
{
"value":1
}
int z = jsonObject.getInt("value");
Non of them worked for me.
I did this and it worked:
To encode as a json:
JSONObject obj = new JSONObject();
obj.put("productId", 100);
To decode:
long temp = (Long) obj.get("productId");
I use a combination of json.get() and instanceof to read in values that might be either integers or integer strings.
These three test cases illustrate:
int val;
Object obj;
JSONObject json = new JSONObject();
json.put("number", 1);
json.put("string", "10");
json.put("other", "tree");
obj = json.get("number");
val = (obj instanceof Integer) ? (int) obj : (int) Integer.parseInt((String) obj);
System.out.println(val);
obj = json.get("string");
val = (obj instanceof Integer) ? (int) obj : (int) Integer.parseInt((String) obj);
System.out.println(val);
try {
obj = json.get("other");
val = (obj instanceof Integer) ? (int) obj : (int) Integer.parseInt((String) obj);
} catch (Exception e) {
// throws exception
}
The question is kind of old, but I get a good result creating a function to convert an object in a Json string from a string variable to an integer
function getInt(arr, prop) {
var int;
for (var i=0 ; i<arr.length ; i++) {
int = parseInt(arr[i][prop])
arr[i][prop] = int;
}
return arr;
}
the function just go thru the array and return all elements of the object of your selection as an integer
For JsonNode use:Integer.parseInt(String.valueOf())

Categories