I am fairly new to Java and I have tried looking up an answer for this for the last couple hours and so far I have nothing.
I am working with the Nobel Prize API for a project and I am getting an error when I try to convert to classes from the Json stream.
My code to read in the stream is this:
Gson gson = new Gson();
String sURL = "http://api.nobelprize.orgv1/laureate.json?bornCountry=Canada"; //just a string
// Connect to the URL using java's native library
URL url = new URL(sURL);
HttpURLConnection request = (HttpURLConnection) url.openConnection();
request.connect();
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //Convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject(); //May be an array, may be an object.
LaureatesMain person = gson.fromJson(rootobj, LaureatesMain.class);
System.out.println(person);
}
I am not checking for errors from the stream yet.
The json stream that I am looking at looks something like this:
{
"laureates": [
{
"id": "140",
// MORE STUFF
"prizes": [
{
"year": "1990",
// MORE STUFF
"affiliations": [
{
"name": "Stanford University",
"city": "Stanford, CA",
"country": "USA"
}
]
}
]
}
]
}
I have a class for the laureates, prizes and affiliations and when it runs on Json like above I have no issue and it goes into the classes fine.
The problem I run into is if there is no entry in the affiliations then for some reason the API flips the {} to [] and gives me the following:
{
"laureates": [
{
"id": "140",
// MORE STUFF
"prizes": [
{
"year": "1990",
// MORE STUFF
"affiliations": [[]
]
}
]
}
]
}
When I run on this one I get Expected BEGIN_OBJECT but was BEGIN_ARRAY at path
$.laureates[###].prizes[0].affiliations[0]
I have tried looking at changing the GsonBuilder and tried to intercept the Json and change it before it goes into the Builder but so far nothing has worked for me.
I have no control over what I get from the API. I can deal with it being an empty class object or a null value in the final structure. This is a fairly early iteration of the project but so far this issue is stopping me from moving on to other things.
Thanks
Answering my own question so I can close it.
I ended up using a Type Adapter so thank you for directing me to that. Wasn't too hard once I knew what I was looking for.
Found really good information in the following java docs at :
https://google.github.io/gson/apidocs/com/google/gson/TypeAdapter.html
https://static.javadoc.io/com.google.code.gson/gson/2.6.2/com/google/gson/stream/JsonReader.html
Related
i'm having a problem with GSON, i'm trying to get a json file and transform them into a list of objects, i have no idea how to solve that, i tried to follow the article below but im recieving this error message below.
article: https://attacomsian.com/blog/gson-read-json-file
test.json
[
{
"code": "sasdsa321",
"items": [
{
"id":"1",
"name":"item1"
},
{
"id":"2",
"name":"item2"
},
...
]
},
...
]
my code
Gson gson = new Gson();
// create a reader
Reader reader = Files.newBufferedReader(Paths.get("test.json"));
// convert JSON array to list of items
List<Item> items= new Gson().fromJson(reader, new TypeToken<List<Item>>() {}.getType());
// print users
items.forEach(System.out::println);
Error message
"com.google.gson.stream.MalformedJsonException: Expected value at line 1 column 1 path $"
I am trying to do JSON parsing. The JSON data is shown below, I am trying to get the "categories". I was able to JSON parse everything else, but I am not sure what does this "categories" belong to, is it a JSONObject, JSONArray, or something else? I am a newbie and self-taught, usually I am familiar that JSONArray has form of "JSONArray": {["content"]}, and the "content" is JSONObject. But in this case, "categories":["content"]. I am trying to parse this "categories", and turn it to string. Thank you for your help.
{
"results": [
{
"type": "Restaurant",
"id": "jfhuiewjkfkdljiahueijkfnlsdiejkl1484391hjk8421k",
"score": 99.9844207764,
"dist": 15.581982823437135,
"info": "search:ta:840369014527642-US",
"poi": {
"name": "RoofTop Bar",
"categorySet": [
{
"id": 184729472943
}
],
"categories": [
"pub food",
"restaurant"
]}
}]
}
This is what I have tried:
groups = new JSONArray();
groups = response.getJSONArray("results");
if (groups.length() > 0) {
JSONObject resultObject = groups.getJSONObject(0);
if (resultObject.has("poi")) {
if (resultObject.getJSONObject("poi").has("name")) {
nameResult = resultObject.getJSONObject("poi").getString("name");
} else {
nameResult = "Information is not available.";
}
if (resultObject.getJSONObject("poi").has("categories")) {
JSONObject categoriesResult;
categoriesResult = resultObject.getJSONObject("categories").toString();
}
results is an array of objects
The first object contains a property called poi
poi contains a property called categories
So using the top to bottom approach, we can arrive at
const categoriesArray = results[0].poi.categories; // gives categories as an array of strings
const categoriesString = categoriesArray.join(",") // gives categories as string, with comma separated values
I am not sure if it is the actual raw data but the poi object where the categories are contained is malformed. It is missing a closing bracket which could be causing parsing issues.
That apart, the field categories from the poi object is a list of strings I am not sure how you want to format it to a string but you could loop through them and do want you want with them.
In order to obtain them you can access them from your object with results[0].poi.categories or loop through the results before accessing the categories with result.poi.categories where result is the variable containing the currently looped result.
EDIT:
From your code sample, assuming response is a JSONObject you can do the following.
Then to obtain categories in a string without the array format, you can loop through the categories and concatenate them to a string.
String categories = resultObject.get("categories").join(", ");
I'm new to JSON and have below file. I have to save the array "steps" in java and need to loop the objects "duration" , "status" and "Keyword".
"steps": [
{
"result": {
"duration": 7128811788,
"status": "passed"
},
"line": 5,
"name": "The Browser is Launched and Smart Business URL is loaded",
"match": {
"location": "Common_Login.the_Browser_is_Launched_and_Smart_Business_URL_is_loaded()"
},
"keyword": "Given "
},]
I tried below but didn't worked.
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader("./target/JSON/Output.json"));
JSONArray jsonArray = (JSONArray) obj;
System.out.println(jsonArray);
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObjectRow = (JSONObject) jsonArray.get(i);
name = (String) jsonObjectRow.get("duration");
id = (String) jsonObjectRow.get("status");
uri = (String) jsonObjectRow.get("name");
status = (String) jsonObjectRow.get("location");
}
Refer here.
There are so many libraries build in for doing this task. But look at the question above.
If you want to use the built-in class from Java you can have a look here:
https://stackoverflow.com/a/17399110/3977134
You are missing the part from the parseJson function in the referenced answer.
For simplicity I'd suggest to you to use org.json which is just one of many good libraries to use for JSON parsing in Java. If you are interested see here:
Parse JSON with org.json
Parsing JSON in Java Using org.json
I have json file in below format.
{
"data":[
{
"prjId": 1,
"name" : "Forj1",
"issue": [
{
"id": 00001,
"status" : "Closed"
},
{
"id": 00002,
"status" : "Open"
}
]
},
{
"prjId": 2,
"name" : "Forj2",
"issue": [
{
"id": 00003,
"status" : "Closed"
},
{
"id": 00004,
"status" : "Open"
}
]
}],
"issueCounter": 7,
"success": true
}
Here "data" is array of projects, and within project attribute there is array of "issue".
So far if I remove "issue" array, I am able to traverse the json to one level down in "data" attribute, If this json has "issue" array I get an error saying missing comma.
javax.json.stream.JsonParsingException: Invalid token=NUMBER at (line no=15, column no=14, offset=242) Expected tokens are: [COMMA]
Below is the code that I have right now. I have two problems with this, one is the error while reading if I place the "issue" attribute, and secondly a way to read the "issue" array and traverse all attributes within.
InputStream fis = new FileInputStream(pathToFile+"data3.json");
JsonReader jsonReader = Json.createReader(fis);
//the error is thrown on below line while reading the above json.
JsonObject jsonObject = jsonReader.readObject();
jsonReader.close();
fis.close();
System.out.println(jsonObject.getInt("issueCounter"));
//reading arrays from json
JsonArray jsonArrayData = jsonObject.getJsonArray("data");
Project [] prj = new Project[jsonArrayData.size()];
int index = 0;
for(JsonValue value : jsonArrayData){
JSONObject jsonObj = new JSONObject(value.toString());
System.out.println(jsonObj.getString("name"));
System.out.println(jsonObj.getInt("prjId"));
//this is also the place where I am stuck, I know I need to construct an array out of it by obtaining issue attribute. Below is very very wrong.
/*
JsonArray jsonArrayIssue = jsonObj.getJsonArray("issue");
for(JsonValue issue : jsonArrayIssue){
JSONObject jsonIssueObj = new JSONObject(issue.toString());
System.out.println(jsonIssueObj.getString("status"));
System.out.println(jsonIssueObj.getInt("id"));
}
*/
}
Any help or pointers is deeply appreciated. I can tweak the json if its required ultimately I need to maintain an array of issues.
The problem as others said is the JSON.
"id": 00001 <-- this is a number, numbers cannot start with a leading zero as per JSON stadard.
If you control the JSON you should tweak it.
Alternatively ff you don't, you can use a less strict parser like org.json.simple https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple
The code will be the same as yours, just adjusted to org.json.simple
try { ...
JSONObject rootJSON = (JSONObject) new JSONParser().parse(jsonString);
JSONArray dataList = (JSONArray) rootJSON.get("data");
for(Object projectObj: dataList.toArray()){
JSONObject project = (JSONObject)projectObj;
JSONArray issueList = (JSONArray) project.get("issue");
for(Object issueObj: issueList.toArray()){
JSONObject issue = (JSONObject) issueObj;
//do something with the issue
}
}
} catch (ParseException e) {
//do smth
e.printStackTrace();
}
Your json data is invalid.You can check here.
http://jsonlint.com
...issue": [{ "id": 00001,
"status": ----------------------^
Your id must be string number,string,boolean.Send 1,2,3,.... as return values and check if it works.
Your code looks okay the problem is the JSON formatting. Specifically the following lines:
"id": 00001,
"id": 00002,
"id": 00003,
"id": 00004,
Basically if you want it in that format you will need to set them as strings by wrapping the values in quotations i.e. "id": "00001" or you can use a valid number i.e. "id": 1
I know its an array, but I am completely new to JSON and need help comprehending how this is structured, here is my attempt at extracting data:
String JSonString = readURL("//my URL is here");
JSONArray s = JSONArray.fromObject(JSonString);
JSONObject Data =(JSONObject)(s.getJSONObject(0));
System.out.println(Data.get("name"));
My JSON data that I have goes like this :
{
"sports": [
{
"name": "basketball",
"id": 40,
"uid": "s:40",
"leagues": [
{
"name": "National Basketball Assoc.",
"abbreviation": "nba",
"id": 46,
"uid": "s:40~l:46",
"groupId": 7,
"shortName": "NBA",
"athletes": []
}
]
}
],
"resultsOffset": 10,
"resultsLimit": 10,
"resultsCount": 1,
"timestamp": "2013-11-18T03:15:43Z",
"status": "success"
}
I dont really have a strong grasp of this stuff so all the help is appreciated.
Here is the idea :
JSONObject root = new JSONObject(yourJsonString);
JSONArray sportsArray = root.getJSONArray("sports");
// now get the first element:
JSONObject firstSport = sportsArray.getJSONObject(0);
// and details of the first element
String name = firstSport.getString("name"); // basketball
int id = firstSport.getInt("id"); // 40
JSONArray leaguesArray = firstSport.getJSONArray("leagues");
// and so on, you can process leaguesArray similarly
It should work (feel free to complain about compile errors if there are any)
Your JSON data is an object (it starts with a curly brace). In the next inner layer, there is a single array (at key "sports"):
String jsonString = readURL("//my URL is here");
JSONObject result = JSONObject(jsonString);
JSONArray sports = result.getJSONArray("sports");
JSONObject sport = sport.getJSONObject(0);
System.out.println(sport.getString("name"));
I might have used another JSON library than you.
JSON means JavaScript Object Notation.
Objects in javascripts are just containers and can be represented by key-value pairs. Please find below notations to understand about json.
Represent objects in json: E.g. Student
{"name" : "Robin", "rollnumber" : "1"}
Represent array in json : E.g. Array of students
[{"name" : "Robin", "rollnumber" : "1"}, {"name" : "Mark", "rollnumber" : "2"}]
You can understand more on JSON from diagrams on this link http://www.json.org/fatfree.html
There are various ways available to to convert JSON to javaobject and javaobject to JSON : One of them is http://wiki.fasterxml.com/JacksonInFiveMinutes
Adding detailed code here along with the imports .
If this helps.
import org.json.JSONException;
import org.json.JSONObject;
public class extractingJSON {
public static void main(String[] args) throws JSONException {
// TODO Auto-generated method stub
String jsonStr = "{\"name\":\"SK\",\"arr\":{\"a\":\"1\",\"b\":\"2\"},\"arrArray\":[{\"a\":\"1\",\"b\":\"2\"}]}";
JSONObject jsonObj = new JSONObject(jsonStr);
String name = jsonObj.getString("name");
System.out.println(name);
String first = jsonObj.getJSONObject("arr").getString("a");
System.out.println(first);
first = jsonObj.getJSONArray("arrArray").getJSONObject(0).getString("a");
System.out.println(first);
}
}