I'm having a bit of trouble parsing the JSON response from YouTube but I need a bit of assistance doing so. I'm attempting to obtain the fields: id, videoId, thumbnails and url - using the following:
private String getUrl(String id) throws IOException, JSONException {
HttpClient client = new DefaultHttpClient();
HttpGet clientGetMethod = new HttpGet(YOUTUBE_INFO_URL.replace("_ID_", id));
HttpResponse clientResponse = null;
clientResponse = client.execute(clientGetMethod);
String infoString = _convertStreamToString(clientResponse.getEntity().getContent());
String urldata=new JSONObject(infoString).getJSONObject("id").getJSONObject("videoId").getJSONArray("thumbnails").getJSONObject(0).getString("url");
return new JSONObject(infoString).getJSONObject("id").getJSONObject("videoId").getJSONArray("thumbnails").getJSONObject(0).getString("url");
}
YouTube API v3 Response:
http://pastebin.com/LKWC2Cbz
However I continually get fatal errors due to incorrect parsing. Can someone spot where I may have gone wrong? I'm specifying the fields I need - however I feel like the structure must not match the JSON response in some manner.
So I assume that infoString contains the JSON response that you pasted to the pastebin link you shared.
This is my first Java program and I'm using Java 8 so things are a little bit different than in your code (I'm using JsonObject for example, not JSONObject, although when reading the program it should be clear what you need to modify)
package stackoverflowyoutubejson;
import java.io.IOException;
import javax.json.*;
public class StackOverflowYoutubeJson {
public static void main(String[] args) {
try {
JsonObject object;
// Instead of making a Http GET request I just read out the JSON file's contents saved down locally
try (JsonReader jsonReader = Json.createReader(StackOverflowYoutubeJson.class.getResourceAsStream("input/youtube-response.json"))) {
object = jsonReader.readObject();
}
// Obtaining the items array
JsonArray items = object.getJsonArray("items");
// Iterating the items array
for(int i = 0; i < items.size(); i++) {
JsonObject item = items.getJsonObject(i);
JsonString id = item.getJsonString("id");
System.out.println("id: " + id);
JsonObject snippet = item.getJsonObject("snippet");
JsonString videoId = snippet.getJsonObject("resourceId").getJsonString("videoId");
System.out.println("videoid: " + videoId);
JsonString url = snippet.getJsonObject("thumbnails").getJsonObject("default").getJsonString("url");
System.out.println("default thumbnail url: " + url);
System.out.println();
}
}
catch(IOException e) {
System.out.println(e);
}
}
}
The output of this program is:
id: "PL7ztmfZ6VHFYVLwdKgxI9lwOWFV_yoCFOK5o9K8KSE2s"
videoid: "PcfLDmkpzto"
default thumbnail url: "https://i.ytimg.com/vi/PcfLDmkpzto/default.jpg"
id: "PL7ztmfZ6VHFYVLwdKgxI9l7VIO-rUMLOT7pjiYSbTRPw"
videoid: "D9ohtWGSl9M"
default thumbnail url: "https://i.ytimg.com/vi/D9ohtWGSl9M/default.jpg"
id: "PL7ztmfZ6VHFYVLwdKgxI9l5gWA-vAfTbxQVrUWaMILLA"
videoid: "B1OluIUHLnY"
default thumbnail url: "https://i.ytimg.com/vi/B1OluIUHLnY/default.jpg"
id: "PL7ztmfZ6VHFYVLwdKgxI9l9A2H_-9HSzVlvT--kLf0TA"
videoid: "LjKpcUJSjtM"
default thumbnail url: "https://i.ytimg.com/vi/LjKpcUJSjtM/default.jpg"
id: "PL7ztmfZ6VHFYVLwdKgxI9l9nWIbKA-8Bnu3v_D6xEKaU"
videoid: "fTSmcQdLyhU"
default thumbnail url: "https://i.ytimg.com/vi/fTSmcQdLyhU/default.jpg"
So basically, if you have a JSON like this:
{
"field1": {
"nestedField1": "nestedValue1",
"nestedField2": "nestedValue2"
},
"field2": "value2"
}
You can access the fields like this:
JSONObject wholeJson = new JSONObject(jsonStringAsDescribedAbove);
JSONString field2 = wholeJson.getJSONString("field2"); // will contain value2
JSONObject field1 = wholeJson.getJSONObject("field1"); // will contain the whole field1 object
JSONString nestedField1 = wholeJson.getJSONObject("field1").getJSONString("nestedField1"); // or field1.getJSONString("nestedField1");, will contain nestedValue1
JSONString nestedField2 = wholeJson.getJSONObject("field1").getJSONString("nestedField2"); // or field1.getJSONString("nestedField2");, will contain nestedValue2
Related
I am very new to this as you can probably tell, but i'm trying to parse a JSON url with Volley using Kotlin in Android Studio. The url contains nested Objects, not nested Arrays.
I can display everything inside "questionnaire", but I only want to display "typeOfQuestion". How do i do that?
MainActivity.kt:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
questionTV = findViewById(R.id.idTVQuestion)
answerTV = findViewById(R.id.idTVAnswer)
typeTV = findViewById(R.id.idTVType)
val queue: RequestQueue = Volley.newRequestQueue(applicationContext)
val request = JsonObjectRequest(Request.Method.GET, url, null, { response ->
loadingPB.setVisibility(View.GONE)
try {
val question: String = response.getString("question")
val answer: String = response.getString("answer")
val typeOfQuestion: String = response.getString("typeOfQuestion")
questionTV.text = question
answerTV.text = answer
typeTV.text = typeOfQuestion
} catch (e: Exception) {
e.printStackTrace()
}
}, { error ->
Log.e("TAG", "RESPONSE IS $error")
Toast.makeText(this#MainActivity, "Fail to get response", Toast.LENGTH_SHORT)
.show()
})
queue.add(request)
}
}
Heres the JSON:
{
"questionnaire": {
"question": "Where do you live?",
"answer": "In the mountains",
"typeOfQuestion": "Informative
}
}
You have object inside another json object.If you need to access field from child object you need to get child jsonObject and then get fields from object.
var questionnaire = response.getJSONObject("questionnaire")
You need to get fields from questionnaire object.Like.
val question: String = questionnaire.getString("question")
val answer: String = questionnaire.getString("answer")
val typeOfQuestion: String = questionnaire.getString("typeOfQuestion")
This is a full-console app in dart. Its not flutter.
I need to import data from a local json file and send it as response. I need to read the data as array of Map in dart. The data is in following format.
{
"users":[
{
"id":1,
"user":"user1",
"password":"p455w0rd"
},
{
"id":2,
"user":"user2",
"pass":"p455w0rd"
}
]
}
Every where I see the Flutter example which imports flutter/services as rootBundle to read into the JSON file. I do not find a way to implement this in pure dart.
Use dart:io and dart:convert.
Simple example below. Remember to add exception handling if the file does not exist or has wrong format.
import 'dart:convert';
import 'dart:io';
Future<List<Map>> readJsonFile(String filePath) async {
var input = await File(filePath).readAsString();
var map = jsonDecode(input);
return map['users'];
}
Below is the sample code which you can use to synchronously read a text/json file as a string, displays its content and creates corresponding objects. This will work without using any flutter classes.
For reading JSON/txt file,user 'dart:io' package.
Once the file has been read as a string, use JsonDecoder class to convert the json into corresponding data model objects
import 'dart:io';
import 'dart:convert';
const String FILEPATH = "C:\\test\\dartlang\\users.json";
const JsonDecoder decoder = JsonDecoder();
class USER {
int? id;
String? user;
String? password;
//{ } - implies named arguments
USER({this.id, this.user, this.password});
#override
String toString() {
return "{id:$id,user:$user,password:$password}";
}
}
void main() {
List<USER>? eMP;
//synchronously read file contents
var jsonString = File(FILEPATH).readAsStringSync();
//print(jsonString);
//pass the read string to JsonDecoder class to convert into corresponding Objects
final Map<String, dynamic> jsonmap = decoder.convert(jsonString);
//DataModel - key = "users", value = "ARRAY of Objects"
var value = jsonmap["users"];
if (value != null) {
eMP = <USER>[];
//Each item in value is of type::: _InternalLinkedHashMap<String, dynamic>
value.forEach((item) => eMP?.add(new USER(id:item["id"],user:item["user"],password:item["password"] )));
}
eMP?.forEach((element) => print(element));
}
Save the following json file in your filepath.
{
"users":[{"id":1,"user":"user1", "password":"p455w0rd"},
{"id":2,"user":"user2","password":"p455w0rd"}
]
}
First import dart:convert.
You can parse data from a JSON file as follows:
Future<void> readJson() async {
final String response = await rootBundle.loadString('assets/sample.json');
final data = await json.decode(response);
final users = data['users'];
// ...
}
I am new to flutter and want to parse the data from a URL that is in json format. The url that I am using is json link .
I want to get the "verse" and "chapter" fields from the json array. I have succeeded in getting the response body in snackbar but not able to get single values. I want to get the "verse" and "chapter" and show then in text box. I am using Dart.
Here is the method that I am using:
_makeGetRequest() async {
// make request
var url = Uri.parse("http://quotes.rest/bible/vod.json");
Response response = await http.get(url);
// sample info available in response
int statusCode = response.statusCode;
Map<String, String> headers = response.headers;
String contentType = headers['content-type'];
String json = response.body;
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(json)));
}
#override
void initState() {
super.initState();
streamingController.config(url: "http://stream.zeno.fm/qa8p6uz2tk8uv");
streamingController.play();
_makeGetRequest();
}
Please help me in getting the proper field values and set them in text box as I am trying to solve it from past two days and have tried all solutions from internet but getting exceptions.
use jsonDecode
Map<String,dynamic> data = jsonDecode(response.body);
String verse = data["contents"]["verse"];
dynamic chapter= data["contents"]["chapter"];
however I recommend modeling your data
I'm trying to do a post request in Android Studio written in Kotlin
I'm posting a JSON object to our server and then the server is returning a JSON object back. But what I'm doing here is decoding the response body as a string and then converting it into the data structure we need. I'm sure there is a better and simpler way to do what I need done.
My current code works but the major issue I'm having is formatting the string if our objects have nested objects which is why I want to figure out a better way to turn the response body into a json object.
I'm not too familiar with many request libraries for kotlin but I have looked into okhttp3 but I'm not sure how to post a json object, attach headers and decode the response body into a json object.
I know for okhttp3 I need to convert the json object to a string to post other than that I'm lost.
Breakdown of what's needed:
Post JSON Object To Server
Send Headers With Post Request
Decode Response Body into JSON Object/ Kotlin Equivalent
Simplify What I'm Trying to Do if Possible
This is the current code I have
private fun postRequestToGetDashboardData() {
val r = JSONObject()
r.put("uid", muid)
r.put("token", mtoken)
SendJsonDataToServer().execute(r.toString());
}
inner class SendJsonDataToServer :
AsyncTask<String?, String?, String?>() {
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
if (result.equals(null)) {
val t = Toast.makeText(this#Home, "No devices to display", Toast.LENGTH_LONG)
t.setGravity(Gravity.CENTER, 0, 0)
t.show()
} else {
intentForUnique.putExtra("FirstEndpointData", result)
var list = handleJson(result)
adapter.submitList(list)
dashboardItem_list.adapter = adapter
adapter.notifyDataSetChanged();
dashboardItem_list.smoothScrollToPosition(0);
}
}
override fun doInBackground(vararg params: String?): String? {
val JsonDATA = params[0]!!
var urlConnection: HttpURLConnection? = null
var reader: BufferedReader? = null
try {
val url = URL("URL");
urlConnection = url.openConnection() as HttpURLConnection;
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Authorization", mtoken);
urlConnection.setRequestProperty("Accept", "application/json");
val writer: Writer =
BufferedWriter(OutputStreamWriter(urlConnection.getOutputStream(), "UTF-8"));
writer.write(JsonDATA);
writer.close();
val inputStream: InputStream = urlConnection.getInputStream();
if (inputStream == null) {
return null;
}
reader = BufferedReader(InputStreamReader(inputStream))
var inputLine: String? = reader.readLine()
if (inputLine.equals("null")) {
return null
} else {
return inputLine
}
} catch (ex: Exception) {
Log.e(TAG, "Connection Failed", ex);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (ex: Exception) {
Log.e(TAG, "Error closing stream", ex);
}
}
}
return null
}
}
private fun handleJson(jsonString: String?): ArrayList<SensorData> {
val jsonArray = JSONArray(jsonString)
val list = ArrayList<SensorData>()
var x = 0
while (x < jsonArray.length()) {
val jsonObject = jsonArray.getJSONObject(x)
list.add(
SensorData(
jsonObject.getInt("deviceId"),
// jsonObject.getString("deviceName"),
jsonObject.getInt("battery"),
jsonObject.getString("dateTime"),
jsonObject.getInt("airValue"),
jsonObject.getInt("waterValue"),
jsonObject.getInt("soilMoistureValue"),
jsonObject.getInt("soilMoisturePercent")
)
)
x++
}
return list
}
So the json data being returned back is an array of this structure (our backend is written in Go)
type Device struct {
DeviceID int `bson:"deviceId" json:"deviceId"`
Battery int `bson:"battery" json:"battery"`
DateTime time.Time `bson:"dateTime" json:"dateTime"`
AirValue int `bson:"airValue" json:"airValue"`
WaterValue int `bson:"waterValue" json:"waterValue"`
SoilMoistureValue int `bson:"soilMoistureValue" json:"soilMoistureValue"`
SoilMoisturePercent int `bson:"soilMoisturePercent" json:"soilMoisturePercent"`
}
I am looking for some help with a datatable conversion into a JObject. I am using C# in visual studio along with the Newtonsoft JSON .net library. I have retrieved my datatable from my database.
From here I took the data table and processed it through this class:
public string DataTableToJSONString(DataTable table)
{
string JSONString = string.Empty;
JSONString = JsonConvert.SerializeObject(table,Formatting.Indented);
return JSONString;
}
Now that the object has been converted to a JSONString successfully (It throws no errors at this point) via the Newtonsoft JSON.net Library, I am unable to parse it into a JObject with this code:
Note: "json" is the string variable I placed the returned value from the DatatabletoDataTableToJSONString() method into..
JObject job = JObject.Parse(json);
I continuously get the following error...
Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.
The reason I need it in the form of a JObject it to pass it into the following post method for an API:
public static async Task<JObject> Post(string url, JObject data)
{
// Create an HttpClient instance
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = CreateBasicHeader(ClientContext.Username, ClientContext.Password);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Send a request asynchronously and continue when complete
var requestbody = new StringContent(data.ToString(), Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(url, requestbody);
dynamic content = await response.Content.ReadAsAsync<JObject>();
// Check that response was successful or throw exception
try
{
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
throw new Exception("Status Code: " + response.StatusCode + "\r\nMessage: " + content[0].ToString(), ex);
}
// Read response asynchronously as a JObject
return content;
}
I would appreciate any help on this as I have been researching for 2 weeks with no luck. This one is really killing me. Thanks in advance to all who take the time to examine this.
UPDATE: I ended up adding in the following bit of code as I realized I was returning an array when I pulled the data table.
string jsonresult = JsonConvert.SerializeObject(dt);
JArray aray = JArray.Parse(jsonresult);
//I then have code for the API login credentials here....
foreach (JObject item in aray)
{
ApiClient.Post(Url, item).Wait();
}
This appears to pass in the JObjects just fine into the post method although I get the following error:"AggregateException was unhandled..." I set a break point and the flaw appears to happen at the:
try
{
response.EnsureSuccessStatusCode();
}
After attempting the response.ensuresuccessstatusCode(); The program of course jumps to the catch....
catch (Exception ex)
{
throw new Exception("Status Code: " + response.StatusCode + "\r\nMessage: " + content.message.ToString(), ex);
}
Again, any help would be appreciated. I am almost there with this. After it posts, I will be done.... Thanks again in advance to everyone. I apologize for being long winded.
Your problem is that JSON has two types of containers: arrays and objects:
An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace).
The corresponding LINQ to JSON class is JObject.
An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).
The corresponding LINQ to JSON class is JArray.
So, how does Json.NET serialize a data table? From the documentation Serialize a DataSet, we can see that each table is serialized as an array.
If you attempt to parse a JSON string whose root object is an array into a JObject, you will get this exception.
Instead, you must return a JArray, or better yet a JToken which is the root class for all JSON entities:
public static async Task<JToken> Post(string url, JObject data)
{
// Create an HttpClient instance
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = CreateBasicHeader(ClientContext.Username, ClientContext.Password);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Send a request asynchronously and continue when complete
var requestbody = new StringContent(data.ToString(), Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(url, requestbody);
dynamic content = await response.Content.ReadAsAsync<JToken>();
// Check that response was successful or throw exception
try
{
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
throw new Exception("Status Code: " + response.StatusCode + "\r\nMessage: " + content[0].ToString(), ex);
}
// Read response asynchronously as a JToken
return content;
}
I am answering this thread and closing it as the original question has technically been answered. I simply converted the JArray into its respective JObjects with the following bit of code.
foreach (JObject item in aray)
{
ApiClient.Post(Url, item).Wait();
}
Although I am still working on debugging, I was technically able to pull the Object out of the array that I got from the data table.
Thanks all!!!!!