This question already has answers here:
How to parse JSON in Java
(36 answers)
Closed 4 years ago.
How do I parse a JSON feed in Android?
Android has all the tools you need to parse json built-in. Example follows, no need for GSON or anything like that.
Get your JSON:
Assume you have a json string
String result = "{\"someKey\":\"someValue\"}";
Create a JSONObject:
JSONObject jObject = new JSONObject(result);
If your json string is an array, e.g.:
String result = "[{\"someKey\":\"someValue\"}]"
then you should use JSONArray as demonstrated below and not JSONObject
To get a specific string
String aJsonString = jObject.getString("STRINGNAME");
To get a specific boolean
boolean aJsonBoolean = jObject.getBoolean("BOOLEANNAME");
To get a specific integer
int aJsonInteger = jObject.getInt("INTEGERNAME");
To get a specific long
long aJsonLong = jObject.getLong("LONGNAME");
To get a specific double
double aJsonDouble = jObject.getDouble("DOUBLENAME");
To get a specific JSONArray:
JSONArray jArray = jObject.getJSONArray("ARRAYNAME");
To get the items from the array
for (int i=0; i < jArray.length(); i++)
{
try {
JSONObject oneObject = jArray.getJSONObject(i);
// Pulling items from the array
String oneObjectsItem = oneObject.getString("STRINGNAMEinTHEarray");
String oneObjectsItem2 = oneObject.getString("anotherSTRINGNAMEINtheARRAY");
} catch (JSONException e) {
// Oops
}
}
Writing JSON Parser Class
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
Parsing JSON Data
Once you created parser class next thing is to know how to use that class. Below i am explaining how to parse the json (taken in this example) using the parser class.
2.1. Store all these node names in variables: In the contacts json we have items like name, email, address, gender and phone numbers. So first thing is to store all these node names in variables. Open your main activity class and declare store all node names in static variables.
// url to make request
private static String url = "http://api.9android.net/contacts";
// JSON Node names
private static final String TAG_CONTACTS = "contacts";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_EMAIL = "email";
private static final String TAG_ADDRESS = "address";
private static final String TAG_GENDER = "gender";
private static final String TAG_PHONE = "phone";
private static final String TAG_PHONE_MOBILE = "mobile";
private static final String TAG_PHONE_HOME = "home";
private static final String TAG_PHONE_OFFICE = "office";
// contacts JSONArray
JSONArray contacts = null;
2.2. Use parser class to get JSONObject and looping through each json item. Below i am creating an instance of JSONParser class and using for loop i am looping through each json item and finally storing each json data in variable.
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
try {
// Getting Array of Contacts
contacts = json.getJSONArray(TAG_CONTACTS);
// looping through All Contacts
for(int i = 0; i < contacts.length(); i++){
JSONObject c = contacts.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String email = c.getString(TAG_EMAIL);
String address = c.getString(TAG_ADDRESS);
String gender = c.getString(TAG_GENDER);
// Phone number is agin JSON Object
JSONObject phone = c.getJSONObject(TAG_PHONE);
String mobile = phone.getString(TAG_PHONE_MOBILE);
String home = phone.getString(TAG_PHONE_HOME);
String office = phone.getString(TAG_PHONE_OFFICE);
}
} catch (JSONException e) {
e.printStackTrace();
}
I've coded up a simple example for you and annotated the source. The example shows how to grab live json and parse into a JSONObject for detail extraction:
try{
// Create a new HTTP Client
DefaultHttpClient defaultClient = new DefaultHttpClient();
// Setup the get request
HttpGet httpGetRequest = new HttpGet("http://example.json");
// Execute the request in the client
HttpResponse httpResponse = defaultClient.execute(httpGetRequest);
// Grab the response
BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), "UTF-8"));
String json = reader.readLine();
// Instantiate a JSON object from the request response
JSONObject jsonObject = new JSONObject(json);
} catch(Exception e){
// In your production code handle any errors and catch the individual exceptions
e.printStackTrace();
}
Once you have your JSONObject refer to the SDK for details on how to extract the data you require.
Related
I am new on JAVA, how to parse the countryname using this API: https://iplist.cc/api
Use JAVA to parse the JSON: https://iplist.cc/api
Get ONLY the "countryname" value.
For example,
If the country name is "countryname": "Germany",
The OUTPUT should be only:
Germany
I tried this but did not work :(
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
// url to make request
private static String url = "https://iplist.cc/api";
// JSON Node names
private static final String COUNTRY_NAME = "countryname";
// contacts JSONArray
JSONArray contacts = null;
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
try {
country = json.getString(COUNTRY_NAME);
}
} catch (JSONException e) {
e.printStackTrace();
}
Thank You!
For such deserialization purpose, I would recommend you to use Gson (or another of this kind).
implementation 'com.google.code.gson:gson:2.8.6'
Prepare IP class for deserialization:
public class IP {
public final String ip;
public final String registry;
public final String countrycode;
public final String countryname;
public final String detail;
public final boolean spam;
public final boolean tor;
public IP(String ip, String registry,
String countrycode, String countryname,
String detail, boolean spam, boolean tor) {
this.ip = ip;
this.registry = registry;
this.countrycode = countrycode;
this.countryname = countryname;
this.detail = detail;
this.spam = spam;
this.tor = tor;
}
}
Deserialize from JSON String with Gson:
IP ip = new Gson().fromJson(json, IP.class);
System.out.println(ip.countryname);
First add org.json library to your project. this is for converting String to JSONObject.
public class HttpGet {
public static String readGetRequestData(String urlToRead) throws IOException {
// System.setProperty("https.proxyHost", "ip");
// System.setProperty("https.proxyPort", "port"); if you got some proxy set it
URL url = new URL(urlToRead);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
return new String(connection.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
}
public static void main(String[] args) throws Exception {
String data = readGetRequestData("https://iplist.cc/api");
try {
JSONObject jsonObject = new JSONObject(data);
System.out.println(jsonObject.get("countryname"));
} catch (JSONException err) {
err.printStackTrace();
}
}
}
result is: Germany
This question already has answers here:
How to parse JSON in Java
(36 answers)
Closed 4 years ago.
How do I parse a JSON feed in Android?
Android has all the tools you need to parse json built-in. Example follows, no need for GSON or anything like that.
Get your JSON:
Assume you have a json string
String result = "{\"someKey\":\"someValue\"}";
Create a JSONObject:
JSONObject jObject = new JSONObject(result);
If your json string is an array, e.g.:
String result = "[{\"someKey\":\"someValue\"}]"
then you should use JSONArray as demonstrated below and not JSONObject
To get a specific string
String aJsonString = jObject.getString("STRINGNAME");
To get a specific boolean
boolean aJsonBoolean = jObject.getBoolean("BOOLEANNAME");
To get a specific integer
int aJsonInteger = jObject.getInt("INTEGERNAME");
To get a specific long
long aJsonLong = jObject.getLong("LONGNAME");
To get a specific double
double aJsonDouble = jObject.getDouble("DOUBLENAME");
To get a specific JSONArray:
JSONArray jArray = jObject.getJSONArray("ARRAYNAME");
To get the items from the array
for (int i=0; i < jArray.length(); i++)
{
try {
JSONObject oneObject = jArray.getJSONObject(i);
// Pulling items from the array
String oneObjectsItem = oneObject.getString("STRINGNAMEinTHEarray");
String oneObjectsItem2 = oneObject.getString("anotherSTRINGNAMEINtheARRAY");
} catch (JSONException e) {
// Oops
}
}
Writing JSON Parser Class
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
Parsing JSON Data
Once you created parser class next thing is to know how to use that class. Below i am explaining how to parse the json (taken in this example) using the parser class.
2.1. Store all these node names in variables: In the contacts json we have items like name, email, address, gender and phone numbers. So first thing is to store all these node names in variables. Open your main activity class and declare store all node names in static variables.
// url to make request
private static String url = "http://api.9android.net/contacts";
// JSON Node names
private static final String TAG_CONTACTS = "contacts";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_EMAIL = "email";
private static final String TAG_ADDRESS = "address";
private static final String TAG_GENDER = "gender";
private static final String TAG_PHONE = "phone";
private static final String TAG_PHONE_MOBILE = "mobile";
private static final String TAG_PHONE_HOME = "home";
private static final String TAG_PHONE_OFFICE = "office";
// contacts JSONArray
JSONArray contacts = null;
2.2. Use parser class to get JSONObject and looping through each json item. Below i am creating an instance of JSONParser class and using for loop i am looping through each json item and finally storing each json data in variable.
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
try {
// Getting Array of Contacts
contacts = json.getJSONArray(TAG_CONTACTS);
// looping through All Contacts
for(int i = 0; i < contacts.length(); i++){
JSONObject c = contacts.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String email = c.getString(TAG_EMAIL);
String address = c.getString(TAG_ADDRESS);
String gender = c.getString(TAG_GENDER);
// Phone number is agin JSON Object
JSONObject phone = c.getJSONObject(TAG_PHONE);
String mobile = phone.getString(TAG_PHONE_MOBILE);
String home = phone.getString(TAG_PHONE_HOME);
String office = phone.getString(TAG_PHONE_OFFICE);
}
} catch (JSONException e) {
e.printStackTrace();
}
I've coded up a simple example for you and annotated the source. The example shows how to grab live json and parse into a JSONObject for detail extraction:
try{
// Create a new HTTP Client
DefaultHttpClient defaultClient = new DefaultHttpClient();
// Setup the get request
HttpGet httpGetRequest = new HttpGet("http://example.json");
// Execute the request in the client
HttpResponse httpResponse = defaultClient.execute(httpGetRequest);
// Grab the response
BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), "UTF-8"));
String json = reader.readLine();
// Instantiate a JSON object from the request response
JSONObject jsonObject = new JSONObject(json);
} catch(Exception e){
// In your production code handle any errors and catch the individual exceptions
e.printStackTrace();
}
Once you have your JSONObject refer to the SDK for details on how to extract the data you require.
I want to carry out the following php query on my remote database
$result = mysqli_query($con->myconn, "SELECT id, stake, user, returns, teams, status FROM `bet` WHERE user = $user") or die(mysql_error());
My only problem is I'm not sure how to modify my JSONParser class so that I can simultaneously pass the user parameter to the database and receive the results. It currently looks like this and allows me only to either retrieve values or send values.
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
// function get json from url
// by making HTTP POST or GET mehtod
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {
// Making HTTP request
try {
// check for request method
if (method == "POST") {
// request method is POST
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} else if (method == "GET") {
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
if (!line.startsWith("<", 0)) {
if (!line.startsWith("(", 0)) {
sb.append(line + "\n");
}
}
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
CODE :
public class DisplayAllBets extends ActionBarActivity {
private String user1 = "user";
private static String url_all_games = "***";
JSONParser jParser = new JSONParser();
private static final String TAG_SUCCESS = "success";
private static final String TAG_GAMELIST = "gamelist";
private static final String TAG_ID = "id";
private static final String TAG_STAKE = "stake";
private static final String TAG_RETURNS = "returns";
private static final String TAG_TEAMS = "teams";
private static final String TAG_STATUS = "status";
JSONArray allgames = null;
private ProgressDialog pDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_all_bets);
// Hashmap for ListView
ArrayList<HashMap<String, String>> gamesList = new ArrayList<HashMap<String, String>>();
// Loading products in Background Thread
class LoadAllGames extends AsyncTask<String, String, String> {
private String id;
private String stake;
private String user;
private String returns;
private String teams;
private String status;
*/
/**
* Before starting background thread Show Progress Dialog
*//*
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(DisplayAllBets.this);
pDialog.setMessage("Loading Bets. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
*/
/**
* getting All products from url
*//*
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_games, "GET", params);
// Check your log cat for JSON reponse
Log.d("All Games: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Games
allgames = json.getJSONArray(TAG_GAMELIST);
// looping through All Products
for (int i = 0; i < allgames.length(); i++) {
JSONObject c = allgames.getJSONObject(i);
// Storing each json item in variable
id = c.getString(TAG_ID);
stake = c.getString(TAG_STAKE);
returns = c.getString(TAG_RETURNS);
status = c.getString(TAG_STATUS);
teams = c.getString(TAG_TEAMS);;
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_ID, id);
map.put(TAG_TEAMS, teams);
map.put(TAG_STAKE, stake);
map.put(TAG_RETURNS, returns);
map.put(TAG_STATUS, status);
// adding HashList to ArrayList
gamesList.add(map);
}
// } else {
// no products found
// Launch Add New product Activity
// Intent i = new Intent(getApplicationContext(),
// NewProductActivity.class);
// Closing all previous activities
// i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// startActivity(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
return "";
}
I am trying to make an app that gets data from url on Android. I noticed that JSON files are different. Some of them start with an arrach name and some not. Those that have the array name like this which "user" is the array name work in my app but those that does not have any array name does not work. For example this.
This is the code that I try to make array an object but it does not work for the second JSON file as it does not find the array name:
//URL to get JSON Array
private static String url = "http://api.worldbank.org/countries/ir?format=json";
//JSON Node Names
private static final String TAG_USER = "user";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_EMAIL = "email";
JSONArray user = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Creating new JSON Parser
JSONParser jParser = new JSONParser();
// Getting JSON from URL
JSONObject json = jParser.getJSONFromUrl(url);
try {
// Getting JSON Array
user = json.getJSONArray(TAG_USER);
JSONObject c = user.getJSONObject(0);
// Storing JSON item in a Variable
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String email = c.getString(TAG_EMAIL);
//Importing TextView
final TextView uid = (TextView)findViewById(R.id.uid);
final TextView name1 = (TextView)findViewById(R.id.name);
final TextView email1 = (TextView)findViewById(R.id.email);
//Set JSON Data in TextView
uid.setText(id);
name1.setText(name);
email1.setText(email);
} catch (JSONException e) {
e.printStackTrace();
}
}
So this example is for the first JSON part. Can you tell me how to have similar code but for the second JSON file please?
So first of all you're not allowed to do Network stuff on the main thread because those things tend to take long (if the server is not responding or the connection is bad or the file you are trying to fetch is big) and if done on the main thread it will block the application on the phone. If your app is not responsive for too long it will be killed automatically from the Android OS. In order to avoid such things you need to use AsyncTasks. These are tasks that can do work in the background while your main thread is still being responsive to user input.
You can read more about AsyncTasks here.
[EDIT]
So answering to your comment on your question: The reason why you get a NetworkOnMainThreadException is because you call jParser.getJSONFromUrl(url); in your main thread (the one where you execute code normally). The reason why this is not allowed is because in the method getJSONFromUrl() you make a HTTP request and have to wait for a response from the given URL. This can take a very long time as I have explained above and would block your application on the phone with the already explained consequences. Now to fix this you need to do something like this:
Before (bad):
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Creating new JSON Parser
JSONParser jParser = new JSONParser();
// Getting JSON from URL
JSONObject json = jParser.getJSONFromUrl(url);
// get the data from your JSONObject
}
Better:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Getting JSON from URL
new JsonRequest().execute(url);
}
private class JsonRequest extends AsyncTask<String, Void, JSONObject>
// I will talk about the parameters to AsyncTask below
#Override
protected JSONObject doInBackground(String... urls) {
// Creating new JSON Parser
JSONParser jParser = new JSONParser();
// Getting JSON from URL
JSONObject json = jParser.getJSONFromUrl(url);
return json;
}
#Override
protected void onPostExecute(JSONObject result) {
// Get the array
JSONArray array = result.getJSONArray("data");
// Display the data
// Import textviews
// and so on..
}
Now about the parameters to AsyncTask:
This type is the type of the parameters given to doInBackground
This type is used for showing a progress bar for example if you download many things you can override a function called onProgressUpdate and could show how many things already have been downloaded on your app so the user knows that something is happening.
This type is the type that doInBackground will return and that onPostExecute has as a parameter.
This way your main thread will keep running and the user won't notice a thing that there is a download going on in the background because it's a seperate task that is running. I hope this made it quite clear if not, just leave another comment and I'll explain more. :)
[\EDIT]
Then the second problem is that the JSONParser from learn2crack can't parse JSONArrays, in other words the function getJSONFromUrl() simply tries to create a new JSONObject from the String it gets from the given url.
Theres basically several ways to fix this, I did a little hack (it invovles little code but you will need more time getting to the data afterwards). I added the following lines into the getJSONFromUrl() method:
if (json.startsWith("[")) {
// We have a JSONArray
try {
jObj = new JSONObject();
jObj.put("data", new JSONArray(json));
} catch (JSONException e) {
Log.d("JSON Parser", "Error parsing JSONArray " + e.toString());
}
return jObj;
}
These lines should be added right above this part:
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
Basically what you will end up with then is that you can simply call getJSONFromUrl() on any url, and if it contains a JSONObject you will get that object, but if it contains a JSONArray you will get a JSONObject with a single field called data which will contain your JSONArray. So you could do something like this:
JSONObject json = jParser.getJSONFromUrl(url);
JSONArray array = json.getJSONArray("data");
And then you have your array (of course surrounded with a try catch for JSONException).
As far as i know there is no specific way to tell whether you are getting json array or json object after you parse it!!!.
The way i would solve this,is to look for starting character of the string data from response.
In your getJSONFromUrl method you get the string from response and then you start parse it into an JsonObject. Before you parse look for starting character based on starting character decide whether you are going for JsonObject or JsonArray.
Am not sure if their is any shorter way to solve this but your problem is a tricky one :) .A lot of other things have to be dealt with since you don't actually know beforehand whether you are going to get jsonobject or jsonarray.
Here is what i have put together:
public interface JsonListener {
public boolean isJsonObejct();
}
Create a class by extending JSONObject and implementing the above interface.
import org.json.JSONException;
import org.json.JSONObject;
public class CustomJSONObject extends JSONObject implements JsonListener {
public CustomJSONObject(String json) throws JSONException {
// TODO Auto-generated constructor stub
super(json);
}
#Override
public boolean isJsonObejct() {
// TODO Auto-generated method stub
return true;
}
}
Create another class by extending JSONArray and implementing the above interface.
import org.json.JSONArray;
import org.json.JSONException;
public class CustomJSONArray extends JSONArray implements JsonListener{
public CustomJSONArray(String json) throws JSONException {
// TODO Auto-generated constructor stub
super(json);
}
#Override
public boolean isJsonObejct() {
// TODO Auto-generated method stub
return false;
}
}
Modify you jsonparseclass so it does not return jsonobject or jsonarray instead it will return Object of type JsonListener.
public class JSONParser {
static InputStream is = null;
static JsonListener jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JsonListener getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
if(json.startsWith("{")){
jObj = new CustomJSONObject(json);
}else{
jObj = new CustomJSONArray(json);
}
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
Now adjust your code to use those:
// Creating new JSON Parser
JSONParser jParser = new JSONParser();
// Getting JSON from URL
JsonListener json = jParser.getJSONFromUrl(url);
if(json.isJsonObejct()){
Log.i("Got","JsonObject "+((CustomJSONObject)json).toString());
}else{
Log.i("Got","JsonArray "+((CustomJSONArray)json).toString());
}
Hopefully you will get some insight from this.
I want to get a JSON object from a Http get response:
Here is my current code for the Http get:
protected String doInBackground(String... params) {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(params[0]);
HttpResponse response;
String result = null;
try {
response = client.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) {
// A Simple JSON Response Read
InputStream instream = entity.getContent();
result = convertStreamToString(instream);
// now you have the string representation of the HTML request
System.out.println("RESPONSE: " + result);
instream.close();
if (response.getStatusLine().getStatusCode() == 200) {
netState.setLogginDone(true);
}
}
// Headers
org.apache.http.Header[] headers = response.getAllHeaders();
for (int i = 0; i < headers.length; i++) {
System.out.println(headers[i]);
}
} catch (ClientProtocolException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return result;
}
Here is the convertSteamToString function:
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
Right now I am just getting a string object. How can I get a JSON object back.
The string that you get is just the JSON Object.toString(). It means that you get the JSON object, but in a String format.
If you are supposed to get a JSON Object you can just put:
JSONObject myObject = new JSONObject(result);
Do this to get the JSON
String json = EntityUtils.toString(response.getEntity());
More details here : get json from HttpResponse
This is not the exact answer for your question, but this may help you
public class JsonParser {
private static DefaultHttpClient httpClient = ConnectionManager.getClient();
public static List<Club> getNearestClubs(double lat, double lon) {
// YOUR URL GOES HERE
String getUrl = Constants.BASE_URL + String.format("getClosestClubs?lat=%f&lon=%f", lat, lon);
List<Club> ret = new ArrayList<Club>();
HttpResponse response = null;
HttpGet getMethod = new HttpGet(getUrl);
try {
response = httpClient.execute(getMethod);
// CONVERT RESPONSE TO STRING
String result = EntityUtils.toString(response.getEntity());
// CONVERT RESPONSE STRING TO JSON ARRAY
JSONArray ja = new JSONArray(result);
// ITERATE THROUGH AND RETRIEVE CLUB FIELDS
int n = ja.length();
for (int i = 0; i < n; i++) {
// GET INDIVIDUAL JSON OBJECT FROM JSON ARRAY
JSONObject jo = ja.getJSONObject(i);
// RETRIEVE EACH JSON OBJECT'S FIELDS
long id = jo.getLong("id");
String name = jo.getString("name");
String address = jo.getString("address");
String country = jo.getString("country");
String zip = jo.getString("zip");
double clat = jo.getDouble("lat");
double clon = jo.getDouble("lon");
String url = jo.getString("url");
String number = jo.getString("number");
// CONVERT DATA FIELDS TO CLUB OBJECT
Club c = new Club(id, name, address, country, zip, clat, clon, url, number);
ret.add(c);
}
} catch (Exception e) {
e.printStackTrace();
}
// RETURN LIST OF CLUBS
return ret;
}
}
Again, it’s relatively straight forward, but the methods I’ll make special note of are:
JSONArray ja = new JSONArray(result);
JSONObject jo = ja.getJSONObject(i);
long id = jo.getLong("id");
String name = jo.getString("name");
double clat = jo.getDouble("lat");
Without a look at your exact JSON output, it's hard to give you some working code. This tutorial is very useful, but you could use something along the lines of:
JSONObject jsonObj = new JSONObject("yourJsonString");
Then you can retrieve from this json object using:
String value = jsonObj.getString("yourKey");
For the sake of a complete solution to this problem (yes, I know that this post died long ago...) :
If you want a JSONObject, then first get a String from the result:
String jsonString = EntityUtils.toString(response.getEntity());
Then you can get your JSONObject:
JSONObject jsonObject = new JSONObject(jsonString);
You need to use JSONObject like below:
String mJsonString = downloadFileFromInternet(urls[0]);
JSONObject jObject = null;
try {
jObject = new JSONObject(mJsonString);
}
catch (JSONException e) {
e.printStackTrace();
return false;
}
...
private String downloadFileFromInternet(String url)
{
if(url == null /*|| url.isEmpty() == true*/)
new IllegalArgumentException("url is empty/null");
StringBuilder sb = new StringBuilder();
InputStream inStream = null;
try
{
url = urlEncode(url);
URL link = new URL(url);
inStream = link.openStream();
int i;
int total = 0;
byte[] buffer = new byte[8 * 1024];
while((i=inStream.read(buffer)) != -1)
{
if(total >= (1024 * 1024))
{
return "";
}
total += i;
sb.append(new String(buffer,0,i));
}
}
catch(Exception e )
{
e.printStackTrace();
return null;
}catch(OutOfMemoryError e)
{
e.printStackTrace();
return null;
}
return sb.toString();
}
private String urlEncode(String url)
{
if(url == null /*|| url.isEmpty() == true*/)
return null;
url = url.replace("[","");
url = url.replace("]","");
url = url.replaceAll(" ","%20");
return url;
}
Hope this helps you..
There is a JSONObject constructor to turn a String into a JSONObject:
http://developer.android.com/reference/org/json/JSONObject.html#JSONObject(java.lang.String)
If your api is response is a java object, then the string that you got from Outputstream should be in json string format such as
{\"name\":\"xyz\", \"age\":21}
. This can be converted to JSON object in many ways, out of which one way is to use google GSON library.
GsonBuilder builder = new GsonBuilder().setPrettyPrinting(); Gson gson = builder.create(); <javaobject> = gson.fromJson(<outputString>, <Classofobject>.class);
One can do it without Gson also, using Jackson, which implements Json Tree Model.
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(responseString);
1)String jsonString = EntityUtils.toString(response.getEntity());
2)JSONObject jsonObject = new JSONObject(jsonString);