JSON from String Builder (Java) - null error - java

I am building a program using a GET API call to pull artist info in an Eclipse/Java console. I get a good connection to the API that prints out JSON but I'm getting error when trying to pull a specific data point: Cannot invoke "org.json.simple.JSONObject.get(Object)" because "nbalbum" is null
I'm very new to Java and JSON so appreciate pointers here.
Here is my code below with an example JSON return at bottom:
public static void main(String[] args) {
{
}
try {
//scanner for artist name user input in console
Scanner artistscan = new Scanner(System.in); //create scanner
System.out.println("Please enter artist name to search:");
String artistname = artistscan.nextLine(); //turn input into string
System.out.println("Here is how many albums this artist has:");
artistscan.close();
String oldurl = "https://api.deezer.com/search/artist?q="
+artistname+"";
String newurl=oldurl.replaceAll(" ", "");
URL url = new URL(newurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.connect();
//Check if connect is made
int responseCode = conn.getResponseCode();
// 200 OK
if (responseCode != 200) {
throw new RuntimeException("HttpResponseCode: " + responseCode);
} else {
StringBuilder informationString = new StringBuilder();
Scanner scanner = new Scanner(url.openStream());
while (scanner.hasNext()) {
informationString.append(scanner.nextLine());
}
//Close the scanner
scanner.close();
//print results
System.out.println(url); //test url is built correctly
System.out.println(informationString);
//Parse JSON results....
// error/returns null:
org.json.simple.parser.JSONParser jsonParser = new JSONParser();
org.json.simple.JSONObject jsonObj = new JSONObject();
jsonObj = (JSONObject) jsonParser.parse(String.valueOf(informationString));
JSONObject nbalbum = (JSONObject) jsonObj.get(0);
System.out.println(nbalbum.get("nb_album"));
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("-------------------------------------");
}}
This is an example JSON return:
{"data":[{"id":566,"name":"Foo Fighters","link":"https:\/\/www.deezer.com\/artist\/566","picture":"https:\/\/api.deezer.com\/artist\/566\/image","picture_small":"https:\/\/e-cdns-images.dzcdn.net\/images\/artist\/54c324b8651addd8c400de22f9dac5c8\/56x56-000000-80-0-0.jpg","picture_medium":"https:\/\/e-cdns-images.dzcdn.net\/images\/artist\/54c324b8651addd8c400de22f9dac5c8\/250x250-000000-80-0-0.jpg","picture_big":"https:\/\/e-cdns-images.dzcdn.net\/images\/artist\/54c324b8651addd8c400de22f9dac5c8\/500x500-000000-80-0-0.jpg","picture_xl":"https:\/\/e-cdns-images.dzcdn.net\/images\/artist\/54c324b8651addd8c400de22f9dac5c8\/1000x1000-000000-80-0-0.jpg","nb_album":37,"nb_fan":4040577,"radio":true,"tracklist":"https:\/\/api.deezer.com\/artist\/566\/top?limit=50","type":"artist"}],"total":1}

Isn't the JSONObject you're getting, have data field & against this field you have JSON array as value. So if this is true, then maybe fetching json array by jsonObj.get("data") & then accessing the value at a certain position would probably work.

Related

How to implement a json parser here?

I created a post request with json and it works pretty well. But now I want to insert the output of this json post request into my database.
So I need to create a json parser to seperate the string like this: "Bestellnummer:1", "Besteller:8195529", "Zeit: 2019-09-27 15:50:07", "Artikelnummer:76194", "Anzahl:1", "Preis:2.968"... (next Artikelnummer and so on...).
Bestellnummer = orderid, Besteller = customerid, Zeit = time, Artikelnummer=articleid, Anzahl = number of article, Preis= price
I tried to do something like a parser in my code, but I never did something like this befor and unfortuntly don't know how to involve this parser in my code.
I hope u can help me
One example for my json Output:
{"Bestellnummer":"1","Besteller":"8195529","Zeit":"2019-09-27 15:50:07","Artikel":[{"Artikelnummer":"76194","Anzahl":"1","Preis":"2.968"},{"Artikelnummer":"61681","Anzahl":"1","Preis":"7.147"},{"Artikelnummer":"111756","Anzahl":"1","Preis":"9.29"},{"Artikelnummer":"14227","Anzahl":"1","Preis":"0"}]}
Code:
private static String dirPath = "https://hauteuchdrum.informatik.uni-siegen.de/propra/aufgaben/ws1920/index.php";
public ArrayList<String> Bestellung(){
File file = new File (dirPath + "//array_complex.json");
ArrayList <String> test = new ArrayList<String>();
try {
String str = "{ \"Bestellnummer\": [1,2,3,4,5] }";
// holt alle 47550 bestellungen vom json
for (int i=1; i<2;i++) {
String POST_PARAMS = "json={\"bid\":\"bid\", \"getorder\":\""+i+"\"}";
//System.out.println(POST_PARAMS);
JSONObject obj1 = new JSONObject(POST_PARAMS);
JSONArray arr=obj1.getJSONArray("Bestellnummer");
for (int z=0; z<arr.length();z++) {
String post_id = arr.getJSONObject(z).getString("Bestellnummer");
System.out.println(post_id);
}
URL obj = new URL("https://hauteuchdrum.informatik.uni-siegen.de/propra/aufgaben/ws1920/index.php");
HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection();
postConnection.setRequestMethod("POST");
postConnection.setRequestProperty("connection", "Keep-Alive");
postConnection.setDoOutput(true);
java.io.OutputStream os = postConnection.getOutputStream();
os.write(POST_PARAMS.getBytes());
os.flush();
os.close();
int responseCode = postConnection.getResponseCode();
//System.out.println("POST Response Code : " + responseCode);
// System.out.println("POST Response Message : " + postConnection.getResponseMessage());
if (responseCode == HttpURLConnection.HTTP_OK) { //success
BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
// System.out.println(response.toString());
test.add(response.toString());
// java.util.Iterator<String> it = test.iterator();
// while (it.hasNext()) {
// System.out.println(it.next());
// }
}
}
}
catch (Exception e) {
System.out.println();
}
return test;
}
If what you want to do is to insert the HTTP response string into database, I strongly recommend you to deserialize the string to POJOs as follows:
Declare 2 classes - MyResponse and Artikel. Artikel is for storing the content of JOSN object in JSON array, and I use List<Artikel> for the JSON array. BTW, I also use #JsonProperty(provided in Jackson) to map JSON keys with uppercase to variables with lowercase.
class MyResponse {
#JsonProperty(value="Bestellnummer")
private String bestellnummer;
#JsonProperty(value="Besteller")
private String besteller;
#JsonProperty(value="Zeit")
private String zeit;
#JsonProperty(value="Artikel")
private List<Artikel> artikel;
//general getters and setters
}
class Artikel {
#JsonProperty(value="Artikelnummer")
private String artikelnummer;
#JsonProperty(value="Anzahl")
private String anzahl;
#JsonProperty(value="Preis")
private String preis;
//general getters and setters
}
Now, you can use Jackson (one of the most popular JSON libraries) to deserialize the HTTP response to our POJOs. And you can manipulate these POJOs for DB operation easily.
ObjectMapper mapper = new ObjectMapper();
MyResponse myResponse = mapper.readValue(response.toString(), MyResponse.class);
myResponse.getArtikel().forEach(System.out::println);
Console output
Artikel [artikelnummer=76194, anzahl=1, preis=2.968]
Artikel [artikelnummer=61681, anzahl=1, preis=7.147]
Artikel [artikelnummer=111756, anzahl=1, preis=9.29]
Artikel [artikelnummer=14227, anzahl=1, preis=0]
Because you provided too less information to come up with a more detailed answer I came up with the following code.
JSONObject main = new JSONObject(data);
String orderNumber = main.getString("Bestellnummer"); // Retrieving the order number
String orderUserId = main.getString("Besteller"); // Retrieving the orderUserId
String time = main.getString("Zeit"); // Retrieving the current time
JSONArray articles = main.getJSONArray("Artikel"); // Getting articles as JSON Array
for (int i = 0; i < articles.length(); i++) { // Looping tough the articles
JSONObject article = articles.getJSONObject(i); // Getting the article JSON Object
String articleNumber = article.getString("Artikelnummer"); // Retrieving the Article number
String amount = article.getString("Anzahl"); // Retrieving the amount
String price = article.getString("Pris"); // Retrieving the price
// Your code...
}
I hope this helps you.

cannot pass the json value to function

I am going to get the JSON from the localhost db. Then, I want to put the json into ArrayList. I want to call the parseJSON function. But the JSON is null. Where I should call the function, thanks so much:))
#Override
protected String doInBackground(Void... voids) {
try {
URL url = new URL(urlWebService);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
StringBuilder sb = new StringBuilder();
InputStream input = con.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(input));
String json;
while ((json = bufferedReader.readLine()) != null) {
sb.append(json + "\n");
}
parseJSON(json);
return sb.toString().trim();
} catch (Exception e) {
return null;
}
}
}
GetJSON getJSON = new GetJSON(
);
getJSON.execute();
}
private void parseJSON(String json) {
Gson gson = new Gson();
Type type = new TypeToken<List<EssayElement>>(){}.getType();
List<EssayElement> mList = gson.fromJson(json, type);
for (EssayElement essayElement : mList){
Log.i("Message: " +
"", essayElement.id + "-" + essayElement.title + "-" + essayElement.essay + "-" + essayElement.date + "-" + essayElement.time);
}
}
null object reference with String"json"
I would suggest using a proper http library that handles making requests for you like Volley or Retrofit... JSON and Error handling are also builtin, so AsyncTask can completely be removed for that purpose
But what you have is fine, only json shouldn't be used after the while loop, it's only the last line of the http response, not the full json (assuming there's multiple lines)
You should really consider parsing the results in the onPostExecute, and possibly even having the parse method return an actual object, or display to the UI
You are appending the string to StringBuilder sb = new StringBuilder();. You have to call like this parseJSON(sb.toString()); cause String json is just a pointer doesn't hold the actual string, you want.
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
String json = sb.toString();
You can instead use my code snippet it's working fine for me. now you can use son variable for your private void parseJSON(String json) function.

Android Studio: Json Parsing loads only 10 objects out of 50 that exists in the URL

I wrote a code that parses Json Data from my WordPress website and put it in a ListView, everything works perfectly, except the fact that it decided to load only 10 Json objects out of nearly 50 that exists in the URL.
After going through over and over my code, and after I've tried everything, I am going to ask here what could be the problem.
This is my class, it is called "getJsondata"
public ArrayList<GamesLibrary> getJsondata(String strurl)
{
ArrayList<GamesLibrary>arrayList=new ArrayList<GamesLibrary>();
String line="";
String res="";
InputStream in=null;
try
{
HttpURLConnection urlConnection=null;
URL url = null;
try
{
URL myURL = new URL(strurl);
URLConnection ucon = myURL.openConnection();
in = ucon.getInputStream();
Log.d("Negev", in.toString());
} catch (Exception e)
{
Log.d("asaf",e.getMessage());
}
BufferedReader br =new BufferedReader(new InputStreamReader(in,"iso-8859-1"));
StringBuffer sb=new StringBuffer("");
StringBuilder b = new StringBuilder();
String input;
while((input=br .readLine())!=null)
{
b.append(input+"\n");
}
in.close();
br.close();
try
{
JSONArray jArray = new JSONArray(b.toString());
for(int i=0;i<jArray.length();i++)
{
Log.d("asaf","try json"+i);
JSONObject json_data = jArray.getJSONObject(i);
String title = json_data.getString("title");
String content = json_data.getString("content");
String content2 = content.replace("\\n", "");
String content3 = Html.fromHtml(content2).toString();
String content4 = content3.replace("\",\"protected\":false}", "");
String title2 = title.replace("{\"rendered\"", "");
title2 = title2.replace("\"}", "");
title2 = title2.replace("\"", "");
title2 = title2.replace(":", "");
title2 = title2.replace("Date", "");
String id = json_data.getString("id");
String slug = json_data.getString("slug");
GamesLibrary gamesLibrary= new GamesLibrary(Integer.valueOf(id),title2,content4,slug);
arrayList.add(gamesLibrary);
Log.d("ff",content3 );
}
}
catch(JSONException e)
{
}
return arrayList;
}
catch (Exception e) {
// TODO: handle exception
}
return null;
}
The code works perfectly, but loads only 10 posts, why is that do you think?
Thank you!
Update:
The arraylist contains only 10 objects, the problem is that it should contain nearly 50...
Update 2: exact Json:
https://docs.google.com/document/d/1wkuAFZWn1jF-_7AO_zvrI4mo1V6paUODvaUW8TAn03k/edit?usp=sharing
I looked at your json, and it contains only 10 items :)
ids: 921, 919, 474 472 470 468 466 464 462 460

Getting string from json object not working

I am using gson library to get the json from an http request.
Everything works fine, except the part where I compare the string I received from the request. Even if the string are exactly the same, for some reason string.equals method fails. And as output it prints always different dates.
What is the reason for this behaviour? What am I missing here?
BufferedReader br;
try{
String url = "http://date.jsontest.com/";
URL request_url = new URL(url);
HttpURLConnection conn = (HttpURLConnection)request_url.openConnection();
conn.setRequestMethod("GET");
if (200 == conn.getResponseCode()){
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String jsonLine = "";
String line ;
while ((line = br.readLine()) != null) {
jsonLine += line;
}
JsonElement jelement = new JsonParser().parse(jsonLine);
JsonObject jobject = jelement.getAsJsonObject();
try{
String result = jobject.get("date").toString();
System.out.println("res: " + result);
if(result.equals("05-29-2017"))
System.out.println("Same date");
else
System.out.println("different date");
}
catch (NullPointerException ex){ }
}
}
catch (JsonSyntaxException ex){}
catch (IOException ex) {}
String result = jobject.get("date").toString();
The above line returns String representation of date, i.e. with quotes around it : "05-29-2017" and that's why equals method returns false ("\"05-29-2017\"".equals("05-29-2017") will be false due to double quotes in the start and end)
If you want the actual value, you need to use getAsString method, e.g. following should work:
String result = jobject.get("date").getAsString();
if(result.equals("05-29-2017"))
System.out.println("Same date");
else
System.out.println("different date");

OutOfMemoryError in StringBuilder and HashSet

I have a JSON file (.json) in Amazon S3. I need to read it and create a new field called Hash_index for each JsonObject. The file is very big, so I am using a GSON library to avoid my OutOfMemoryError in reading the file. Below is my code. Please note that I am using GSON
//Create the Hashed JSON
public void createHash() throws IOException
{
System.out.println("Hash Creation Started");
strBuffer = new StringBuffer("");
try
{
//List all the Buckets
List<Bucket>buckets = s3.listBuckets();
for(int i=0;i<buckets.size();i++)
{
System.out.println("- "+(buckets.get(i)).getName());
}
//Downloading the Object
System.out.println("Downloading Object");
S3Object s3Object = s3.getObject(new GetObjectRequest(inputBucket, inputFile));
System.out.println("Content-Type: " + s3Object.getObjectMetadata().getContentType());
//Read the JSON File
/*BufferedReader reader = new BufferedReader(new InputStreamReader(s3Object.getObjectContent()));
while (true) {
String line = reader.readLine();
if (line == null) break;
// System.out.println(" " + line);
strBuffer.append(line);
}*/
// JSONTokener jTokener = new JSONTokener(new BufferedReader(new InputStreamReader(s3Object.getObjectContent())));
// jsonArray = new JSONArray(jTokener);
JsonReader reader = new JsonReader( new BufferedReader(new InputStreamReader(s3Object.getObjectContent())) );
reader.beginArray();
int gsonVal = 0;
while (reader.hasNext()) {
JsonParser _parser = new JsonParser();
JsonElement jsonElement = _parser.parse(reader);
JsonObject jsonObject1 = jsonElement.getAsJsonObject();
//Do something
StringBuffer hashIndex = new StringBuffer("");
//Add Title and Body Together to the list
String titleAndBodyContainer = jsonObject1.get("title")+" "+jsonObject1.get("body");
//Remove full stops and commas
titleAndBodyContainer = titleAndBodyContainer.replaceAll("\\.(?=\\s|$)", " ");
titleAndBodyContainer = titleAndBodyContainer.replaceAll(",", " ");
titleAndBodyContainer = titleAndBodyContainer.toLowerCase();
//Create a word list without duplicated words
StringBuilder result = new StringBuilder();
HashSet<String> set = new HashSet<String>();
for(String s : titleAndBodyContainer.split(" ")) {
if (!set.contains(s)) {
result.append(s);
result.append(" ");
set.add(s);
}
}
//System.out.println(result.toString());
//Re-Arranging everything into Alphabetic Order
String testString = "acarpous barnyard gleet diabolize acarus creosol eaten gleet absorbance";
//String testHash = "057 1$k 983 5*1 058 52j 6!v 983 03z";
String[]finalWordHolder = (result.toString()).split(" ");
Arrays.sort(finalWordHolder);
//Navigate through text and create the Hash
for(int arrayCount=0;arrayCount<finalWordHolder.length;arrayCount++)
{
if(wordMap.containsKey(finalWordHolder[arrayCount]))
{
hashIndex.append((String)wordMap.get(finalWordHolder[arrayCount]));
}
}
//System.out.println(hashIndex.toString().trim());
jsonObject1.addProperty("hash_index", hashIndex.toString().trim());
jsonObject1.addProperty("primary_key", gsonVal);
jsonObjectHolder.add(jsonObject1); //Add the JSON Object to the JSON collection
jsonHashHolder.add(hashIndex.toString().trim());
System.out.println("Primary Key: "+jsonObject1.get("primary_key"));
//System.out.println(Arrays.toString(finalWordHolder));
//System.out.println("- "+hashIndex.toString());
//break;
gsonVal++;
}
System.out.println("Hash Creation Completed");
}
catch(Exception e)
{
e.printStackTrace();
}
}
When this code is executed, I got the following error
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2894)
at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:117)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:407)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at HashCreator.createHash(HashCreator.java:252)
at HashCreator.<init>(HashCreator.java:66)
at Main.main(Main.java:9)
[root#ip-172-31-45-123 JarFiles]#
Line number 252 is - result.append(s);. It is Inside the HashSet loop.
Previously, it generated OutOfMemoryError in line number 254. Line number 254 is - set.add(s); it is also inside the HashSet array.
My Json files are really really big. Gigabytes and Terabytes. I have no idea about how to avoid the above issue.
Use a streaming JSON library like Jackson.
Read in a some JSON, add the hash, and write them out.
Then read in some more, process them, and write them out.
Keep going until you have processed all the objects.
http://wiki.fasterxml.com/JacksonInFiveMinutes#Streaming_API_Example
(See also this StackOverflow post: Is there a streaming API for JSON?)

Categories

Resources