Parsing JSON strings from URLs (RESTful webservice) using GSON libraries. Android

Before reading: I used GSON downloadable libraries in this program. http://webscripts.softpedia.com/script/Development-Scripts-js/Other-Libraries/Gson-71373.html

I have been trying to parse JSON for quite some time, but every time I try to get a string from a URL, the program does not work. It does not interrupt, does not close, and no errors occur. It just does not perform parsing. My program is designed for analysis from http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo and has a refresh button to restart the parsing process so that it updates the information. If I use a hard-coded JSON string, the program works fine. I even put a string that should be extracted from the url; but I can't seem to get it directly. I use the GSON libraries.

In the code, I provided comments to explain my thought process. Please note that I have two different methods that try to use the url (I thought the original error might have been wrong, so I tried to use another), I grabbed the straw. Please help me. Thanks.

My code is:

package com.android.testgson; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.URI; import java.net.URL; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.google.gson.Gson; public class GSONTestActivity extends Activity { /** Called when the activity is first created. */ //String test = ""; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView tv = (TextView)findViewById(R.id.textViewInfo); syncButtonClickListener(); runJSONParser(tv); } private void syncButtonClickListener() { Button syncButton = (Button)findViewById(R.id.buttonSync); syncButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { TextView tv = (TextView)findViewById(R.id.textViewInfo); runJSONParser(tv); } }); } public InputStream getJSONData(String url){ // create DefaultHttpClient HttpClient httpClient = new DefaultHttpClient(); URI uri; // for URL InputStream data = null; // for URL JSON try { uri = new URI(url); HttpGet method = new HttpGet(uri); // Get URI HttpResponse response = httpClient.execute(method); // Get response from method. data = response.getEntity().getContent(); // Data = Content from the response URL. } catch (Exception e) { e.printStackTrace(); } return data; } public void runJSONParser(TextView tv){ try{ Gson gson = new Gson(); //Reader r = new InputStreamReader(getJSONData("http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo")); /**I tried parsing the URL, but it didn't work. No error messages, just didn't parse.*/ //Reader r = new InputStreamReader(getJSONData("android.resource://"+ getPackageName() + "/" + R.raw.yourparsable)); /**I tried parsing from local JSON file. Didn't work. Again no errors. The program simply stalls. */ //String testString = "{\"weatherObservation\":{\"clouds\":\"few clouds\",\"weatherCondition\":\"n/a\",\"observation\":\"LSZH 041320Z 24008KT 210V270 9999 FEW022 SCT030 BKN045 05/01 Q1024 NOSIG\",\"windDirection\":\"240\",\"ICAO\":\"LSZH\",\"elevation\":\"432\",\"countryCode\":\"CH\",\"lng\":\"8.516666666666667\",\"temperature\":\"5\",\"dewPoint\":\"1\",\"windSpeed\":\"08\",\"humidity\":\"75\",\"stationName\":\"Zurich-Kloten\",\"datetime\":\"2012-01-04 13:20:00\",\"lat\":\"47.46666666666667\",\"hectoPascAltimeter\":\"1024\"}}"; /**If I parse this string. The parser works. It is the same exact string like in the URL.*/ //String failString = "{\"status\":{\"message\":\"the hourly limit of 2000 credits demo has been exceeded. Please throttle your requests or use the commercial service.\",\"value\":19}}"; /**Even if the url delivers this string (because the hourly limit would be reached), the string is still parsed correctly.*/ String json = readUrl("http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo"); /**At this point I tried a different means of accessing the URL but still I had the exact same problem*/ Observation obs = gson.fromJson(json, Observation.class); // "json" can be replaced with r, testString, failString to see all my previous results. if (obs.getWeatherObservation()!=null) { tv.setText("Clouds - " + obs.getWeatherObservation().getClouds() + "\nTemperature - " + obs.getWeatherObservation().getTemperature() + "\nWind Speed - " + obs.getWeatherObservation().getWindSpeed() + "\nHumidity - " + obs.getWeatherObservation().getHumidity()); } else if (obs.getStatus()!=null) { tv.setText("Message - " + obs.getStatus().getMessage() + "\nValue - " + obs.getStatus().getValue()); } }catch(Exception ex){ ex.printStackTrace(); } } public static String readUrl(String urlString) throws Exception { BufferedReader reader = null; try{ URL url = new URL(urlString); reader = new BufferedReader(new InputStreamReader (url.openStream())); StringBuffer buffer = new StringBuffer(); int read; char[]chars = new char[1024]; while ((read = reader.read(chars)) != -1) buffer.append(chars, 0, read); return buffer.toString(); } finally { if (reader != null) reader.close(); } } } 
+6
source share
3 answers

Like Sergey, I found that the included org.json.* library on Android is much easier to use than GSON .

For example, in your scenario, your JSON parsing code would look like this.

 String jsonData = readUrl("http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo"); JSONObject weatherJSONObject = new JSONObject( jsonData ); try { // Not sure the format of your data, but you would want something like this String clouds = weatherJSONObject.getString("clouds"); } catch (JSONException e) { e.printStackTrace(); } 

You would also benefit from AsyncTask or Thread . You never want to run lengthy operations on a user interface thread, because the user interface will seem unresponsive and sluggish.

The following is an example of how you can use AsyncTask to achieve your goal. Read more about it here.

 private class FetchJSONDataTask extends AsyncTask<String, Void, JSONObject> { // This gets executed on a background thread protected JSONObject doInBackground(String... params) { String urlString = params[0]; String jsonData = readUrl( urlString ); JSONObject weatherJSONObject = new JSONObject( jsonData ); return weatherJSONObject; } // This gets executed on the UI thread protected void onPostExecute(JSONObject json) { //Your function that takes a json object and populates views setUpViews( json ); } } 

And to complete your task, you must run this code in your activity.

 FetchJSONDataTask task = new FetchJSONDataTask(); task.execute( new String[] { "http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo" } ); 

Note. This code has not been tested, but it should be a general idea.

+2
source

I parsed json using org.json. *

http://www.json.org/java/index.html Documents in Android 4. http://developer.android.com/reference/org/json/package-summary.html (as an example)

You can download the jar here http://repo1.maven.org/maven2/org/json/json/20090211/json-20090211.jar

I would also like to use your http requests in another thread and only then redraw your user interface. Read about android.os.Handler too for this purpose.

thanks

0
source

The JSON response is usually gzipped, try this in the getJSONData () method:

 ... ... uri = new URI(url); HttpGet method = new HttpGet(uri); // Get URI HttpResponse response = httpClient.execute(method); // Get response from method. InputStream in = response.getEntity().getContent(); GZIPInputStream gin = new GZIPInputStream(in); BufferedReader reader = new BufferedReader(new InputStreamReader(gin)); String line = null; while ((line = reader.readLine()) != null) { jsonResponse.append(line); } reader.close(); ... ... 
0
source

Source: https://habr.com/ru/post/905631/


All Articles