I am pulling all the values of an assessment's questions and answers out of two tables that have auto generated table names and column names. They are made server side with .csv files. It's pretty bad but I found a way using SELECT * statements in PHP. Anyways in my PHP file I have two arrays, questions and answers. I combine them and make a JSON Array like this
try {
$success = 1;
if (!empty($questions) && !empty($answers)) {
$combo = array_combine($questions, $answers);
// success
echo $success;
// echoing JSON response
echo json_encode($combo);
} else {
$response["success"] = 0;
echo json_encode($response);
}
} catch (PDOException $e) {
die($e->getMessage());
}
Now the JSON comes out as desired like this
{
"1": "4",
"Store #": " 0560",
"How many microwave circuits did you run?": " 3",
"How many new ovens did you deliver to the store?": " 1",
"How many new racks did you deliver to the store?": " 5",
...
...
}
The left side of the : contains the question and the right contains the answer. Just like I wanted.
The problem is my app will never know how much data this JSON Array will have or what will be inside it. So using my normal method of parsing this info will not work. I would under normal circumstances use something like this
class Load extends AsyncTask<String, Void, String> {
protected void onPreExecute() {
//progress bar etc
....
}
protected String doInBackground(String... args) {
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
Log.v("RESPONSE", "Success!");
// products found: getting Array of Questions
questions = json.getJSONArray(TAG_QUESTIONS);
// looping through All Questions
for (int i = 0; i < questions.length(); i++) {
JSONObject c = questions.getJSONObject(i);
// Storing each JSON item in variable
String name = c.getString(TAG_NAME);
String field = c.getString(TAG_FIELD);
String value = c.getString(TAG_VALUE);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_NAME, name);
map.put(TAG_FIELD, field);
map.put(TAG_VALUE, value);
infoList.add(map);
}
....
This however requires you to set some sort of identifier for your tags in PHP and/or know whats coming across so you can tell the code how to parse the Strings etc.
So can you parse JSON with unknown data? If so, how?
Thanks in advance
EDIT
I'm working on what I think is a solution but I need some help. Here is the code I'm using inside doInBackground()
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
info = json.getJSONArray(TAG_INFO);
for (int i = 0; i < info.length(); i++) {
if (info != null) {
for (int j = 0; j < info.length(); j++) {
clientList.add(info.get(j).toString());
}
}
}
for (String s : clientList) {
Log.v("CHECKING S", s);
s.split(":");
Log.v("CHECKING S SPLIT", s);
values.add(s);
Log.v("CHECKING VALUES 0", values.get(0));
mQuestions.add(values.get(0));
Log.v("CHECKING VALUES 1", values.get(1));
mAnswers.add(values.get(1));
}
}
But the response stays in JSON and does not split it at all.
The log.v Looks like this
06-27 23:26:03.419: V/CHECKING S SPLIT(32233): {"Were any of the steamers gas?":" yes","Voltage readings on Turbo Chef 4":" 34","Voltage readings on Turbo Chef 3":" 43","Voltage readings on Turbo Chef 2":" 54","Did you label all the outlets?":" yes","Voltage readings on Turbo Chef 1":" 64","How many new ovens did you deliver to the store?":" 1","If yes, did you cap the water lines?":" yes","Phone #":" (740) 389-1174","Has all new equipment been installed & have you confirmed it is all working properly?":" yes","How many new racks did you deliver to the store?":" 5","Are all oven circuits tied into electrical shut down for hood?":" yes","How many Back steamers did you remove?":" none","Date":" 6-24-13","Zip":" 43302","How many oven circuits did you run?":" 2","How many microwave circuits did you run?":" 3","If yes, did you cap the gas lines?":" yes","Did you remove the existing FRONT steamers?":" yes","Did you remove the existing BACK steamers?":" no","Voltage readings on microwave circuit 1":" 57","City":" Marion","Voltage readings on microwave circuit 3":" 92","If yes, how? Shunt Tripp or Contactor":" shunt tripp","Voltage readings on microwave circuit 2":" 87","How many front steamers did you remove?":" 2","1":"4","State":" OH","Store #":" 0560","How many existing steamers did you remove for disposal off-site?":" none","Address":" 1318 Mount Vernon Avenue","Tech Name":" Jon Doe"}
They all look like this, none of them are split and they are still in JSON form. Any ideas?
I think you could change the structure of json which you returned.
Maybe like the blow
{
"1": "4",
"Store #": " 0560",
"How many microwave circuits did you run?": " 3",
"How many new ovens did you deliver to the store?": " 1",
"How many new racks did you deliver to the store?": " 5",
...
...
}
to
{
questions: [
{
question: "1",
answer: "4"
},
{
question: "Store",
answer: "0560"
},
{
question: "How many microwave circuits did you run",
answer: "3"
},
{
question: "How many new ovens did you deliver to the store?",
answer: "1"
},
{
question: "How many new racks did you deliver to the store?",
answer: "5"
}
]
}
and parse json as jsonarray
i don't know about php, but i can achieve something like that in perl using key value
you can read here for more info about key value in php, hope it can help you http://php.net/manual/en/language.types.array.php
i think the problem is you only parse JSON array once instead twice
you need to parse the JSON array for the second time to parse question - answer list
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
info = json.getJSONArray(TAG_INFO);
for (int i = 0; i < info.length(); i++) {
if (info != null) {
//parse JSON Array for the second time to parse question - answer
JSONArray jarray = new JSONArray(info.getString(i));
for (int j = 0; j < jarray.length(); j++) {
clientList.add(jarray.getString(j));
}
}
}
Related
I am fetching a string from my MySql DB on and online server using webservice in JSON format.
I am able to see that Android Studio is fetching it correctly as I see it in debugging mode.
But when I go ahead and add it to a List list, I get nothing.
Here's some more info:
What I am getting:
{"products":[{"veg_name_eng":"Corn","veg_name_hindi":"मक्का"}],"success":1}
My concern is with: "veg_name_hindi":"मक्का"
When I go ahead and try to put it in a dataitem list, I get nothing:
public static List<DataItem> dataItemList;
dataItemList.add(jsonObject.getString(veg_name_eng),jsonObject.getString(veg_name_hindi))
veg_name_eng and veg_name_hindi are the column names at my table.
After the above code I get dataItemList = null, So nothing is adding to it.
In my server side MySql DB, I am using UTF-8 encoding.
I am using android studio.
UPDATE 1:
I am parsing the JSON as :
JSONObject jsonObject = new JSONObject(myJSONString);
veg_list = jsonObject.getJSONArray("products");
try {
while (TRACK < veg_list.length()) {
JSONObject jsonObject = veg_list.getJSONObject(TRACK);
addItem(new DataItem(jsonObject.getString(veg_name_eng), jsonObject.getString(veg_name_hindi)));
TRACK = TRACK + 1;
}
} catch (JSONException e) {
e.printStackTrace();
}
// and the addItem function is as follows:
private static void addItem(DataItem item) {
dataItemList.add(item); //While Debugging, I can see that value of item is correct. (i.e., item: DataItem{veg_name_eng='Cork', veg_name_hindi='मक्का'} )
dataItemMap.put(item.getVeg_id(), item);
}
Firstly, Make a model of the your JSON String using
http://json2java.azurewebsites.net/
and then map your JSON String to your Model using Gson. It's much easy to use.
Another way to get your required String for this particular result is parse json string yourself.
For Example :
String vegNameEng,vegNameHindi;
vegNameEng = vegNameHindi = "";
try{
JSONObject obj = new JSONObject(yourJsonString);
JSONArray arr = obj.getJSONArray("products");
vegNameEng = arr.getJSONObject(0).getString("veg_name_eng");
vegNameHindi = arr.getJSONObject(0).getString("veg_name_hindi");
}catch(JSONException ex){
}
Now vegNameEng and vegNameHindi have the required data.
I figured out, It was a silly mistake, the variable I was using to put data into the database was overwritten by some other variable with the same name. Closing the thread for now. Thanks #Umer-Farooq.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have an e-commerce application and it works perfectly when 5 to 10 users are using it.
But it becomes really slow when it is used by 50-60 people.
Currently I am using MySQL & PHP.
I am calling .php file which has MySQL connectivity code. And from there I am fetching JSON response.
Below is my code:
class Items extends AsyncTask<String, String, String> {
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("id", Itemid));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_allitems, "GET",
params);
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
products = json.getJSONArray(TAG_ITEMS);
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_ITEMID);
String name = c.getString(TAG_NAME);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_PID, id);
map.put(TAG_NAME, name);
// adding HashList to ArrayList
productsList.add(map);
}
This is my PHP code:
$result = mysql_query("SELECT * FROM item_master") ;
// check for empty result
if (mysql_num_rows($result) > 0) {
$response["items"] = array();
while ($row = mysql_fetch_array($result)) {
// temp user array
$item = array();
$item["id"] = $row["id"];
$item["code"] = $row["code"];
$item["name"] = $row["name"];
$item["description"] = $row["description"];
$item["price"] = $row["price"];
$item["image1"] = $row["image1"];
// push single product into final response array
array_push($response["items"], $product);
}
// success
$response["psuccess"] = 1;
....
}
So what are the best approaches for optimization in this scenario ? When more than 1000 users will access this app, the app should be responsive and load items quickly.
On the server side, you need to look into techniques for managing a large number of connections, such as enabling servers to handle high-volume traffic, as well as network-level issues like dynamic load balancing.
On the client side, you can make use of Volley with okHttp. You'd also have to enable the usage of okHttp on the server side for that to work properly.
References:
1. Tactics for using PHP in a high-load site.
2. Separating dynamic and static content on high traffic website.
3. How to implement Android Volley with OkHttp 2.0?
4. Using SPDY on Your Web Server.
I am working on an android app which is retrieving information from a MySQL database.
The android app is posting to a PHP REST web service and the web service is returning JSON data.
What I am currently trying to do is get a list of databases on the MySQL server in alphabetical order. When the JSON is printed to the logcat it seems to be in the right order but when I call json.names() on the JSONObject in android it then has the databases in the wrong order.
For example, the logcat might shown it as db1, db2, db3, db4 but when the array is returned from json.names() its then appears to be in a random order. For example db4, db1, db3, db2.
Is there a particular reason for this and how can I stop this from happening.
Thanks for any help you can provide
Below is the code that processes the JSON
public void processConnectDBResult(IConnectDB iConnectDb, JSONObject json)
{
ArrayList<String> databases = new ArrayList<String>();
ArrayList<String> tables = null;
HashMap<String, List<String>> dbAndTables = new HashMap<String, List<String>>();
try
{
//Retrieve the array of the databases
JSONArray databasesJson = json.names();
for (int i = 0; i < databasesJson.length(); i++)
{
databases.add(databasesJson.getString(i));
//Retrieve the tables array from the database array
JSONArray tablesJson = json.getJSONArray(databasesJson.getString(i));
tables = new ArrayList<String>();
for (int j = 0; j < tablesJson.length(); j++)
{
tables.add(tablesJson.getString(j));
}
dbAndTables.put(databases.get(i), tables);
}
iConnectDb.processDatabaseRetrievalResult("SUCCESS", "", databases, dbAndTables);
}
catch (Exception ex)
{
}
}
I've been toying around with this for a little while and I'm looking for some help. I have an ArrayList that I turn into a JSONArray and then place inside JSONObject. The problem is my formatting. Allow me to show you.
I get the values for my ArrayList and add them like so (small code snippet)
if (v instanceof EditText) {
String answer = ((EditText) v).getText().toString();
if (answer.equals("")) {
error.setText(v.getTag().toString()
+ " Needs an answer");
((EditText) v).setHint("Fill me out!");
((EditText) v).setHintTextColor(getResources()
.getColor(R.color.red_bg));
} else {
error.setText("");
}
String question = v.getTag().toString();
String combo = question + ": " + answer;
myList.add(combo);
Log.v("INFO", "Storing: " + combo);
}
This works, but adding the ":" is the start of my problems. The log prints out
06-19 12:13:33.630: V/INFO(3272): Storing: Height: 6`4
Now when I create my JSON to be sent over I use the following
if (error.getText().toString().equals("")) {
JSONObject json = new JSONObject();
JSONArray jArray = new JSONArray(myList);
try {
json.putOpt("array", jArray);
} catch (JSONException e) {
e.printStackTrace();
}
Again, this works. Now the problem clearly illustrated, it prints out JSON like this
{
"array":
[
"Store #: 00608",
"Phone #: null",
"Address: 3014 N. SCOTTSDALE RD.",
"City: SCOTTSDALE",
"Zip: 85251",
"State: AZ",
"Height: 6`4",
"Weight: 230",
"Ethnicity: White",
"Age: 23",
"Eye Color: Blue",
"Favorite Food: Thai",
"Comments: awesome"
]
}
If you're familiar with JSON you know I've goofed it here. I was merely trying to keep the question and answer together. However by adding the ":" to the middle it looks like I'm trying to use question as the key and answer as the value (kind of). Anyways in the end this looks like legitimate JSON, and it is, but it doesn't work the way I need it to.
My question is, should I just make "question" the key, and "answer" the value?
If so how would I go about creating my JSONArray so that my JSON looks like this
{
"array":
[
"Store #" : "00608",
"Phone #" : "null",
"Address" : "3014 N. SCOTTSDALE RD.",
"City" : "SCOTTSDALE",
"Zip" : "85251",
"State" : "AZ",
"Height" : "6`4",
"Weight" : "230",
....
]
}
So that a simple
var_dump(json_decode($json));
var_dump(json_decode($json, true));
in PHP will provide me with the data I need server side.
or alternatively would it just be simpler to keep this format and split the strings as I parse them server side? Whichever answer you choose please supply a few lines of code with to illustrate your answer. As you can tell I'm a visual person.
Thanks for the help, I hope this helps other people in the future as well!
You can solve this a bunch of ways. If you want to keep the formatting the way it is you just need to process your strings first. When you get values from your ArrayList just split the combo into parts
int splitPoint = combo.indexOf(":")
String key = combo.substring(0, splitPoint);
String value = combo.substring(splitPoint + 1);
Once you split the key and value out just create a new JSONObject and add the key and value as a string
JSONObject jObject = new JSONObject();
jObject.put(key, value);
This will add the JSONString to its own JSONObject. Then you can add this object to the JSONArray that you want to create
JSONArray jArray = new JSONArray();
jArray.puJSONObject(jObject);
I broke this down in to parts but if you just decalre your JSONArray ouside a for loop or some other iterator and loop through your ArrayList, processing each combo string and adding the resulting object to a JSONArray you can acheive the desired result
I am not sure that you can do the following in JSON
[ "key":"value, ...."].
You may be able to do it with Key Value object pairs, as in
[ {"key":"value"},...]
If you do it with objects, you will have to create a new object for each pair, and it might become pretty complicated since the key in JSON corresponds with the name of an instance variable.
My suggestion is to leave it the way you have it now and split the strings. I am not familiar with PHP, but it should be as simple as looping through the JSON array and calling something like split(':') on the strings.
You can make a JSONObject with dynamic keys like so:
{
"Store #" : "00608",
"Phone #" : "null",
"Address" : "3014 N. SCOTTSDALE RD.",
"City" : "SCOTTSDALE",
"Zip" : "85251",
"State" : "AZ",
"Height" : "6`4",
"Weight" : "230",
....
}
The question what is simpler, can only be answered by you yourself, as obviously you implement the App and the Server part. So whatever works best for you is the right way.
Performance-wise, joining strings on one side and splitting them on the other side is not the best, but it also depends on how many entries there are in your array.
I have a set up where it is returning a possibly decent amount of info. Here is the logcat:
04-17 22:38:21.886: DEBUG/TestMYSQL(12603): Result of sql:
[{"id":"1","front_text":"the dog was so cute","back_text":"its name was dolly"},
{"id":"2","front_text":"plants use the sun","back_text":"isn't that interesting"},
{"id":"3","front_text":"plants can use the sun to create","back_text":"energy"},
{"id":"4","front_text":"a plant also needs minerals","back_text":"from the soil"},
{"id":"5","front_text":"without water the plant would","back_text":"probably die"},
{"id":"6","front_text":"plants are little machines","back_text":"who love to eat"}]
To gain this info, I have it execute a php file. Here is some pertinent Java, android code:
.....
result = sb.toString();
Log.d(TAG, "Result of sql: " + result);
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
// parse json data
JSONObject json_data = null;
try {
JSONArray jArray = new JSONArray(result);
for (int i = 0; i < jArray.length(); i++) {
json_data = jArray.getJSONObject(i);
}
return json_data;
It turns results into a jsonObject, to which I can play with.
So here is a step before, the query part in php:
include 'connectMySQL.php';
mysql_select_db("card_db");
$q=mysql_query("SELECT * FROM ".$packname);
while($e=mysql_fetch_assoc($q)){
$output[]=$e;
}
print(json_encode($output));
mysql_close();
The problem is I only seem to have access to the FINAL... eh row. That is, in the above data, I can only seem to access id:6 row.
I'm looking at the auto_complete and JSONOBJECTs but I don't have enough experience to figure this out at the moment, and it is late.
Any ideas on how to loop through the jsonObject in java?
Let me take a minute and analyze the structure for a second before turning in. I don't know much about JSON, but here is what it looks like:
I query the database with tables I've set up, blah blah.
It returns rows of data.
I suppose my question then is how does a row of key value pairs get encoded into a JSON OBJECT, and how can I access different 'rows'?
You're overwriting the JSONObject referenced by json_data in each iteration of the loop. So at the end, it always returns the last element in jArray.
Since you need to return multiple objects, you could:
simply return the jArray to the calling function. However, this means that the caller will have to deal with the details of the data transfer implementation and if you decided to change libraries or move over to XML, it'll break a lot of code and make it much harder.
return an array or List of the actual objects that the calling code is aware of and should be dealing with. For example, you might declare a value-object (VO) that has id, front_text, back_text and for each JSONObject in jArray, you'd create a new VO and put it into an array and return that.
public class MyVO
{
final public String id;
final public String frontText;
final public String backText;
public MyVO(String id, String ft, String bt)
{
this.id = id;
this.frontText = ft;
this.backText = bt;
}
}
List<MyVo> vos = new ArrayList<MyVO>();
JSONArray jArray = new JSONArray(result);
for (int i = 0; i < jArray.length(); i++) {
json_data = jArray.getJSONObject(i);
vos.add(new MyVO(json_data.getString("id"), json_data.getString("front_text"), json_data.getString("back_text"));
}
In the calling code, you could then go over the VOs:
for(MyVO vo : vos)
{
//vo.id or vo.frontText or vo.backText
}