Trying to extract from JSON when it's null - java

Will try to explain my question here.
I have a program that is suppose to parse through an incoming JSON-file that I receive from a web-crawler.
public static void Scan(Article article) throws Exception
{
//When running program, creates a error text-file inside java Project folder
File file = new File("errorlogg.txt");
FileWriter fileWriter = new FileWriter(file, true);
// if file doesn't exists, then create it
if (!file.exists())
{
file.createNewFile();
}
//Setting up an URL HttpURLConnection given DOI
URL urlDoi = new URL (article.GetElectronicEdition());
//Used for debugging
System.out.println("Initial DOI: " + urlDoi);
//Transform from URL to String
String doiCheck = urlDoi.toString();
//Redirect from IEEE Xplore toe IEEE Computer Society
if(doiCheck.startsWith("http://dx."))
{
doiCheck = doiCheck.replace("http://dx.doi.org/", "http://doi.ieeecomputersociety.org/");
urlDoi = new URL(doiCheck);
}
HttpURLConnection connDoi = (HttpURLConnection) urlDoi.openConnection();
// Make the logic below easier to detect redirections
connDoi.setInstanceFollowRedirects(false);
String doi = "{\"url\":\"" + connDoi.getHeaderField("Location") + "\",\"sessionid\":\"abc123\"}";
//Setting up an URL to translation-server
URL url = new URL("http://127.0.0.1:1969/web");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json");
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(doi);
writer.flush();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null )
{
//Used to see of we get something from stream
System.out.println(line);
//Incoming is JSONArray, so create new array and parse fill it with incoming information
JSONArray jsonArr = new JSONArray(line);
JSONObject obj = jsonArr.getJSONObject(0);
//Check if names from DBLP is the same as translators get
//AuthorName, from field creators
JSONArray authorNames = obj.getJSONArray("creators");
ArrayList<Author> TranslationAuthors = new ArrayList<Author>();
Here is the bit of the code that I'm talking about. As you can see I wanna run this code when I get some information from the bufferreader.
My problem is that my program doesn't seem to skip when I don't get a valid JSON. Instead it runs to this line of code:
JSONArray authorNames = obj.getJSONArray("creators")
And then is forced to exit since it can't get the field "creators" since there is none.
How can I do to make sure that my program don't encounter this problem? How can I easy put it in the error-logg file that I create that I could't collect any information.

I think you are working with a org.json.JSONObject? If that's so, there is a has method, which can be used to avoid the JSONException in case the key does not exist.
JSONArray authorNames = null;
if (obj.has("creators")) {
authorNames = obj.getJSONArray("creators");
}

Related

JSON data not able to capture

I write a program to capture the JSON response from the server which contain some needed information I needed. I discovered that sometime my program will not able to capture the correct JSON string and sometime it's works well with no problem. I try to check my code for capturing the response and have no idea on it. When I check the JSON string from server, it's contain the field I want but my program not able to capture the correct data.
This is my JSON String
"info":{
      "reason":"Fine",
      "boolean":false,
      "post":{
         "actions":"",
         "actions_In_process":"Checked",
         "destination":"C%3ApdfFdoc%20edipdfFdestinationpdfFexample.pdf",
         "file_type":"pdf",
       
      },
This is my program for capture the JSON string and the field I need is action_In_process
String Url1 = "http://IP:port/etc/";
HttpURLConnection con = (HttpURLConnection) Url1.openConnection();
con.setRequestMethod("GET");
con.connect();
int responseCode = con.getResponseCode();
if(responseCode == 200)
{
try
{
InputStream is = con.getInputStream();
BufferedReader read = new BufferedReader (new InputStreamReader(is));
StringBuffer buffer = new StringBuffer();
String data = "" ;
while((data = read.readLine() ) != null )
{
buffer.append(data);
}
String JsonData = buffer.toString();
JSONObject jobj = new JSONObject(JsonData);
JSONObject process_info = jobj.getJSONObject("info");
JSONObject pi = process_info.getJSONObject("post");
String action_run = pi.getString("actions_In_process");
System.out.println("Process:" +action_run);
What I had found out is sometime the Process showing is blank but when I get back the JSON data and I found out the field I need is inside the JSON response. Please share your opinion on this issues
This is the message showing my compiler if I not able to capture the correct JSON string
Process :
If in normal condition
Process : check
BufferedReader's readline() is blocking.

Parsing JSON Object from a JSON array

I am currently developing an app and need to parse JSON objects from inside an unnamed array.
I can only manage to parse JSON arrays with a name such as this one: http://jsonparsing.parseapp.com/jsonData/moviesDemoItem.txt.
The code that I used for the one above is
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String asd = buffer.toString();
JSONObject parentObject = new JSONObject(asd);
JSONArray parentArray = parentObject.getJSONArray("movies");
JSONObject fObject = parentArray.getJSONObject(0);
String movie = fObject.getString("movie");
int year = fObject.getInt("year");
return movie + year;
The code includes "movies" which is the array name .
What should I change to parse only the objects from within a JSON array such as https://restcountries.eu/rest/v1/all?
Your countries list is simply an array. Doesn't need a name.
Simply replace
JSONObject parentObject = new JSONObject(asd);
with
JSONArray parentObject = new JSONArray(asd);
See this post for how to iterate over that array to parse the remainder of the objects.
How to parse JSON in Android
Starting something like
for (int i=0; i < parentObject.length(); i++) {
Alternatively, Volley's JsonArrayRequest would be useful, or learning about Retrofit+Gson would be even better if you don't feel like manually parsing the JSON data yourself.

HttpURLConnection response is incorrect

When using this code below to make a get request:
private String get(String inurl, Map headers, boolean followredirects) throws MalformedURLException, IOException {
URL url = new URL(inurl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setInstanceFollowRedirects(followredirects);
// Add headers to request.
Iterator entries = headers.entrySet().iterator();
while (entries.hasNext()) {
Entry thisEntry = (Entry) entries.next();
Object key = thisEntry.getKey();
Object value = thisEntry.getValue();
connection.addRequestProperty((String)key, (String)value);
}
// Attempt to parse
InputStream stream = connection.getInputStream();
InputStreamReader isReader = new InputStreamReader(stream );
BufferedReader br = new BufferedReader(isReader );
System.out.println(br.readLine());
// Disconnect
connection.disconnect();
return connection.getHeaderField("Location");
}
The resulting response is completely nonsensical (e.g ���:ks�6��﯐9�rђ� e��u�n�qש�v���"uI*�W��s)
However I can see in Wireshark that the response is HTML/XML and nothing like the string above. I've tried a myriad of different methods for parsing the InputStream but I get the same result each time.
Please note: this only happens when it's HTML/XML, plain HTML works.
Why is the response coming back in this format?
Thanks in advance!
=== SOLVED ===
Gah, got it!
The server is compressing the response when it contains XML, so I needed to use GZIPInputStream instead of InputSream.
GZIPInputStream stream = new GZIPInputStream(connection.getInputStream());
Thanks anyway!
use an UTF-8 encoding in input stream like below
InputStreamReader isReader = new InputStreamReader(stream, "UTF-8");

HttpURLConection - JSON Response isn't Complete

I am trying to send a request to the Grooveshark API using POST Payload and their requested methods, and I have found a problem. Allow me to show you my code first.
public void getResponse() throws Exception
{
if(service.equals("Grooveshark")) link += getHmacMD5(privateGroovesharkKey, jsonInfo.toString());
if(requestedMethod.equals("GET")) infoURL = new URL(link+arguments);
else infoURL = new URL(link);
HttpURLConnection connection = (HttpURLConnection) infoURL.openConnection();
connection.setRequestMethod(requestedMethod);
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
if(service.equals("Grooveshark"))
{
connection.setRequestProperty("Content-Type","application/json");
OutputStream output = connection.getOutputStream();
output.write(jsonInfo.toString().getBytes());
}
else if(requestedMethod.equals("POST") || requestedMethod.equals("PUT"))
{
OutputStream output = connection.getOutputStream();
output.write(arguments.getBytes());
}
connection.connect();
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null)
sb.append(line).append('\n');
setJsonResult(sb.toString());
System.out.println(jsonResult);
jsonFinal = new JSONObject(jsonResult);
connection.disconnect();
}
I have got that code up here in my project, and I can successfully send requested to any API Webservice that uses JSON in their responses. Now there's only a problem: In Android, it does not give me the WHOLE answer. I've tried running the code on a separate Java (no Android) project, and I get the following output. Although, if I run it on Android, the Log shows me the following:
{"header":{"hostname":"RHL073"},"result":{"songs":[{"SongID":5443351,"SongName":"??????\u00b7???? (FINAL FANTASY XII????)","ArtistID":713,"ArtistName":"Final Fantasy","AlbumID":898007,"AlbumName":"Final Fantasy XII Original Soundtrack","CoverArtFilename":"","Popularity":1214500005,"IsLowBitrateAvailable":tr
And it stops on that tr. Has it anything to do with the parsing of the file that I actually apply afterwards? I don't think it is, but just in case, here it is [This is how I call the search, JSONHandler being the object that contains the code provided above]:
public void performSearch() throws Exception
{
JSONObject search = new JSONObject();
search.put("method", method);
JSONObject header = new JSONObject();
header.put("wsKey", key);
JSONObject parameters = new JSONObject();
parameters.put("query", getSearchQuery());
parameters.put("country", "Portugal");
parameters.put("limit", limit);
parameters.put("offset", "");
search.put("header", header);
search.put("parameters", parameters);
JSONHandler jsonHandler = new JSONHandler(link, search, "Grooveshark", "POST", "");
JSONObject finalResult = jsonHandler.getJsonFinal();
JSONArray songs = finalResult.getJSONObject("result").getJSONArray("songs");
ArrayList<Result> allResults = new ArrayList<Result>();
for(int i = 0; i < songs.length(); i++)
{
JSONObject inner = (JSONObject) songs.get(i);
String name = inner.getString("SongName");
int ID = inner.getInt("SongID");
String artist = inner.getString("ArtistName");
Result res = new Result(name, artist, ID);
res.setAlbumName(inner.getString("AlbumName"));
boolean low = inner.getBoolean("IsLowBitrateAvailable");
int bit = 0;
if(low) bit = 1;
else bit = 0;
res.setIsLowBitRateAvailable(bit);
}
setResults(allResults);
}
As you can clearly see, I am using the json.org library. I really don't understand what's the problem here. Has anyone got any idea as to why?

Using Java to send data to a form on a website hosted locally

I have a program in Java where I retrieve contents from a database.
Now I have a form in the program, and what I want to do is, on the press of a button, some string (text) content retrieved from the database, should be sent over to a website that I'm hosting locally. The content so sent, should be displayed on the website when refreshed.
Can someone guide me as to how I can achieve this (the sending of data to be displayed over the website)?
Will appreciate a lot, if you could kindly show some sample snippets or give me a reference to some tutorial that can help.
---- Okay so i found a link to a snippet that's supposed to do this, but im unable to understand at this stage as to how exactly this snippet works...can someone please guide me into knowing this better ?
here's the code
try {
// Construct data
String data = URLEncoder.encode("key1", "UTF-8") + "=" + URLEncoder.encode("value1", "UTF-8");
data += "&" + URLEncoder.encode("key2", "UTF-8") + "=" + URLEncoder.encode("value2", "UTF-8");
// Send data
URL url = new URL("http://hostname:80/cgi");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
// Process line...
}
wr.close();
rd.close();
} catch (Exception e) {
}
I'm not sure on how you store and manage any of the records but from Java you can send a HTTP Post to the Url (In your case http://localhost/, probably).
Have a look at http://www.exampledepot.com/egs/java.net/post.html for a snippet on how to do this.
Your Website could then store the received information in a database and display it when you refresh.
Update heres the function
Just a side not this is by no means the best way to do this and I have no idea on how this scales but for simple solutions this has worked for me in the past.
/**
* Posts a Set of forms variables to the Remote HTTP Host
* #param url The URL to post to and read
* #param params The Parameters to post to the remote host
* #return The Content of the remote page and return null if no data was returned
*/
public String post(String url, Map<String, String> params) {
//Check if Valid URL
if(!url.toLowerCase().contains("http://")) return null;
StringBuilder bldr = new StringBuilder();
try {
//Build the post data
StringBuilder post_data = new StringBuilder();
//Build the posting variables from the map given
for (Iterator iter = params.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
String key = (String) entry.getKey();
String value = (String)entry.getValue();
if(key.length() > 0 && value.length() > 0) {
if(post_data.length() > 0) post_data.append("&");
post_data.append(URLEncoder.encode(key, "UTF-8"));
post_data.append("=");
post_data.append(URLEncoder.encode(value, "UTF-8"));
}
}
// Send data
URL remote_url = new URL(url);
URLConnection conn = remote_url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(post_data.toString());
wr.flush();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = rd.readLine()) != null) {
bldr.append(inputLine);
}
wr.close();
rd.close();
} catch (Exception e) {
//Handle Error
}
return bldr.length() > 0 ? bldr.toString() : null;
}
You would then use the function as follows:
Map<String, String> params = new HashMap<String, String>();
params.put("var_a", "test");
params.put("var_b", "test");
params.put("var_c", "test");
String reponse = post("http://localhost/", params);
if(reponse == null) { /* error */ }
else {
System.out.println(reponse);
}
The big question is how will you authenticate the "update" from your Java program to your website?
You could easily write a handler on your website, say "/update" which saves the POST body (or value of a request parameter) to a file or other persistent store but how will you be sure that only you can set that value, instead of anybody who discovers it?

Categories