From a Rest API, I get json data in the following format:
[
{
"id": "1",
"item": "tea",
"price": "7.5",
"image": "http:\/\/192.168.1.3\/CI\/images\/tea.jpg",
"veg": "0",
"category": "drinks"
},
{
"id": "2",
"item": "coffee",
"price": "10",
"image": "http:\/\/192.168.1.3\/CI\/images\/coffee.jpg",
"veg": "0",
"category": "drinks"
}
]
From the API I get Json as a string and it contains backslashes in front of url's forward slashes, which is according to the json encoding specification. And I am correctly able to json_decode and get url from php. In android I store the json string in a variable named "menu_json".
Then I am trying to parse and get the image url from it using the following code:
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
try{
JSONObject menuApiObj = new JSONObject(menu_json);
JSONArray menuObj = menuApiObj.getJSONArray("menu");
for (int i = 0; i < menuObj.length(); i++){
JSONObject row = menuObj.getJSONObject(i);
rowString = row.getString("image");
imageUrl = row.toString();
Log.e("rowString", rowString);
Log.e("imageUrl", imageUrl);
}
The output I get is:
{
"id": "1",
"item": "tea",
"price": "7.5",
"image": "tea.jpg",
"veg": "0",
"category": "drinks"
}
The image field is supposed to be:
http://192.168.1.3/CI/images/tea.jpg
But instead I get just:
tea.jpg
When json_decode the API response in PHP, I get the correctly decoded url. But in Android, I am not getting the correctly decoded url in image field.
Please help!
Here is the complete API response:
{"menu":[{"id":"1","item":"tea","price":"7.5","image":"tea.jpg","veg":"0","category":"drinks"},{"id":"2","item":"cofee","price":"10","image":"coffee.jpg","veg":"0","category":"drinks"},{"id":"3","item":"crispy chicken","price":"160","image":"crispy-chicken.jpg","veg":"0","category":"curries"}],"cat_wise":[{"category":"drinks","items":[{"id":"1","item":"tea","price":"7.5","image":"http:\/\/192.168.1.3\/CI\/images\/tea.jpg","veg":"0","category":"drinks"},{"id":"2","item":"cofee","price":"10","image":"http:\/\/192.168.1.3\/CI\/images\/coffee.jpg","veg":"0","category":"drinks"}]},{"category":"curries","items":[{"id":"3","item":"crispy chicken","price":"160","image":"http:\/\/192.168.1.3\/CI\/images\/crispy-chicken.jpg","veg":"0","category":"curries"}]},{"category":"main","items":[]}]}
I'm not sure what Json library you're using, but it looks like org.json. I thought your code looked sane, so I implemented it and do not see the output that you are seeing. My guess is that your input data isn't what you expect it to be.
final JSONArray menuObj = new JSONArray("[\n" +
" {\n" +
" \"id\": \"1\",\n" +
" \"item\": \"tea\",\n" +
" \"price\": \"7.5\",\n" +
" \"image\": \"http://192.168.1.3/CI/images/tea.jpg\",\n" +
" \"veg\": \"0\",\n" +
" \"category\": \"drinks\"\n" +
" },\n" +
" {\n" +
" \"id\": \"2\",\n" +
" \"item\": \"coffee\",\n" +
" \"price\": \"10\",\n" +
" \"image\": \"http://192.168.1.3/CI/images/coffee.jpg\",\n" +
" \"veg\": \"0\",\n" +
" \"category\": \"drinks\"\n" +
" }\n" +
"]");
for (int i = 0; i < menuObj.length(); i++){
final JSONObject row = menuObj.getJSONObject(i);
System.out.println("imageUrl: " + row.getString("image"));
System.out.println("rowString: " + row);
}
Output:
imageUrl: http://192.168.1.3/CI/images/tea.jpg rowString:
{"image":"http://192.168.1.3/CI/images/tea.jpg","item":"tea","price":"7.5","veg":"0","id":"1","category":"drinks"}
imageUrl: http://192.168.1.3/CI/images/coffee.jpg rowString:
{"image":"http://192.168.1.3/CI/images/coffee.jpg","item":"coffee","price":"10","veg":"0","id":"2","category":"drinks"}
To parse JSON Array :
JSONArray jArray = jObject.getJSONArray("menu");
for (int i = 0; i < jArray.length(); i++) {
JSONObject innerjObject =jArray.getJSONObject(i);
String image =innerjObject.getString("image");
array_list.add(image);
}
output: http://192.168.1.3/CI/images/tea.jpg
And to display this image to imageview use library :
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
using Loadimagview method of library load image in imageview
Related
I have a JSON String and convert it to JSONObject.
I want to get specific data from the JSONObject, and every time the JSONObject changes its structure, sometimes it's in an array inside the JSON and sometimes not.
example:
the first time the JSON arrives like this
{
"id": "1",
"Name": "Jack",
"Value": {
"data": [
{"time": "2023", "age": "22"}
]
}}
the second time
{
"age": "22",
"time": "2023",
"Value": {
"data": [
{"Name": "Jack", "id": "1" }
]
}}
if I want to get the name in the first JSON
jsonObject.getString("Name")
and for the second one, I would use
jsonObject.getJSONArray("data").getJSONObject(0).getString("Name")
is there a way I can get the value dynamically regardless of where the keys are?
If your API come from an another team or an external provider, the first thing I would suggest to you, is to clearly define a contract. Otherwise, you can use the isNull(String key) method of JSONObject to check if the key exists or not.
An example here:
JSONObject jsonObject = new JSONObject(YOUR_JSON_STRING);
String nameValue;
if(jsonObject.isNull("Name")) {
nameValue = jsonObject.getJSONObject("Value")
.getJSONArray("data")
.getJSONObject(0)
.getString("Name");
} else {
nameValue = jsonObject.getString("Name");
}
System.out.println(nameValue);
If the JSON strings are always in a similar fashion then you can try a little parser method as provided below. It returns a Key/Value (String/Object) Map:
public static java.util.Map<String, Object> mapJsonObject(String jsonString) {
String json = jsonString
.replaceAll("(?i)[\\[\\]\\{\\}\"]|\"?value\"?:|\"?data\"?:|\n?", "")
.replaceAll("\\s+", " ");
String[] keyValueParts = json.split("\\s*,\\s*");
java.util.Map<String, Object> map = new java.util.HashMap<>();
for (String str : keyValueParts) {
String[] pts = str.split("\\s*:\\s*");
map.put(pts[0].trim(), pts[1]);
}
return map;
}
To use:
String jsonString = "{\n"
+ " \"id\": \"1\",\n"
+ " \"Name\": \"Jack\",\n"
+ " \"Value\": {\n"
+ " \"data\": [\n"
+ " {\"time\": \"2023\", \"age\": \"22\"}\n"
+ " ]\n"
+ "}}";
java.util.Map<String, Object> map = mapJsonObject(jsonString);
System.out.println(map);
The console window will display:
{id=1, time=2023, age=22 , Name=Jack}
You may consider library Josson.
https://github.com/octomix/josson
Deserialization
Josson josson1 = Josson.fromJsonString(
"{" +
" \"id\": \"1\"," +
" \"Name\": \"Jack\"," +
" \"Value\": {" +
" \"data\": [" +
" {\"time\": \"2023\", \"age\": \"22\"}" +
" ]" +
" }" +
"}");
Josson josson2 = Josson.fromJsonString(
"{ " +
" \"age\": \"22\"," +
" \"time\": \"2023\"," +
" \"Value\": {" +
" \"data\": [" +
" {\"Name\": \"Jack\", \"id\": \"1\" }" +
" ]" +
" }" +
"}");
Query
*() is a multi-level wildcard search. It returns the first resolvable element.
System.out.println(josson1.getString("coalesce(Name, *().Name)"));
// Output: Jack
System.out.println(josson2.getString("coalesce(Name, *().Name)"));
// Output: ["Jack"]
// It is because "Name" is inside array "data".
System.out.println(josson1.getString("coalesce(Name, *().Name).first()"));
// Output: Jack
System.out.println(josson2.getString("coalesce(Name, *().Name).first()"));
// Output: Jack
// Added function first() to extract the value.
This is the json which I am getting
{
"id": 21,
"code": "import scala.collection.JavaConversions._;import java.io.File;def getFileTree(f: File): Stream[File] =f #:: (if (f.isDirectory){ f.listFiles().toStream} else{ Stream.empty});getFileTree(new File(\"/home/datagaps/Downloads/\")).filter(_.getName.endsWith(\".json\")).foreach(println);",
"state": "available",
"output": {
"status": "ok",
"execution_count": 21,
"data": {
"text/plain": "/home/datagaps/Downloads/santanu.json\nimport scala.collection.JavaConversions._\nimport java.io.File\ngetFileTree: (f: java.io.File)Stream[java.io.File]\n"
}
},
"progress": 1
}
This is the code which I have written to access the String.
String output=getGETRequestResponse(uri).getJSONObject("output").getJSONObject("data").getString("text/plain");
org.json.JSONException: JSONObject["output"] is not a JSONObject.
at org.json.JSONObject.getJSONObject(JSONObject.java:736)
at com.datagaps.livyservice.service.LivyServerServiceImpl.getFilePaths(LivyServerServiceImpl.java:229)
at com.datagaps.LivyProject.LivyServiceApplication.main(LivyServiceApplication.java:53)
while running the code i am getting the following exception.
You can try something like this:
String output=getGETRequestResponse(uri).getJSONObject("output").getJSONObject("data").toString();
ObjectMapper mapper = new ObjectMapper();
Map<String, String> map = mapper.readValue(output, Map.class);
System.out.ptintln(map.get("text/plain"));
Let me know if what you get.
You can do this also:
String data = "{\n" +
" \"id\": 21,\n" +
" \"code\": \"import scala.collection.JavaConversions._;import java.io.File;def getFileTree(f: File): Stream[File] =f #:: (if (f.isDirectory){ f.listFiles().toStream} else{ Stream.empty});getFileTree(new File(\\\"/home/datagaps/Downloads/\\\")).filter(_.getName.endsWith(\\\".json\\\")).foreach(println);\",\n" +
" \"state\": \"available\",\n" +
" \"output\": {\n" +
" \"status\": \"ok\",\n" +
" \"execution_count\": 21,\n" +
" \"data\": {\n" +
" \"text/plain\": \"/home/datagaps/Downloads/santanu.json\\nimport scala.collection.JavaConversions._\\nimport java.io.File\\ngetFileTree: (f: java.io.File)Stream[java.io.File]\\n\"\n" +
" }\n" +
" },\n" +
" \"progress\": 1\n" +
"}";
//Here data is response which tou get from getGETRequestResponse(uri) so we can replace it like : String data = getGETRequestResponse(uri)
JSONObject jsonRootObject = new JSONObject(data);
final String value = jsonRootObject.getJSONObject("output").getJSONObject("data").getString("text/plain");
System.out.println("text/plain value: " + value);
I have been using JsonPath. However after an issue yesterday where I discovered that the default JsonSmartJsonProvider didn't report an error with an invalid document at parse time, I modified my setup to use Jackson as below
public JsonPathExtractor(String document) throws DocumentFormatException
{
try
{
Configuration.setDefaults(new Configuration.Defaults()
{
private final JsonProvider jsonProvider = new JacksonJsonProvider();
private final MappingProvider mappingProvider = new JacksonMappingProvider();
#Override
public JsonProvider jsonProvider()
{
return jsonProvider;
}
#Override
public MappingProvider mappingProvider()
{
return mappingProvider;
}
#Override
public Set<Option> options()
{
return EnumSet.noneOf(Option.class);
}
});
// Get an object representation of the JSON to allow values to be extracted
this.document = Configuration.defaultConfiguration().jsonProvider().parse(document);
}
catch(Exception e)
{
throw new DocumentFormatException("Invalid JSON document", e);
}
}
However I see a difference in behaviour, in that if I get a path which has a few fields, they are not quoted, whereas they were when using JsonSmartJsonProvider.
Example JSON
{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 25,
"height_cm": 167.6,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [],
"spouse": null
}
With the call:
Object obj = JsonPath.read(document, "$.phoneNumbers");
When using JacksonMappingProvider I get
[{type=home, number=212 555-1234}, {type=office, number=646 555-4567}]
When using JsonSmartJsonProvider I get:
[{"type":"home","number":"212 555-1234"},{"type":"office","number":"646 555-4567"}]
If I want Jackson to behave the same way, is there something else that I can configure?
There's a difference between the way in which Jackson has handled the values and the way in which they are printed out.
When using JsonSmartJsonProvider this line ...
JsonPath.read(parse, "$.phoneNumbers");
... returns a JSONArray and the toString() method - which is called when you 'print' the JSONArray instance is smart enough to know it is dealing with JSON so it prints that state as a JSON string. For example:
[{"type":"home","number":"212 555-1234"},{"type":"office","number":"646 555-4567"}]
But when you use a JacksonJsonProvider then this line ...
JsonPath.read(parse, "$.phoneNumbers");
... returns a List of LinkedHashMap and the toString() implementation invoked when you 'print' that instance is not JSON aware so it prints this:
[{type=home, number=212 555-1234}, {type=office, number=646 555-4567}]
If you want to print JSON when using the JacksonJsonProvider then you have to print it using something which is JSON aware. Here's an example:
String payload = "{\n" +
" \"firstName\": \"John\",\n" +
" \"lastName\": \"Smith\",\n" +
" \"isAlive\": true,\n" +
" \"age\": 25,\n" +
" \"height_cm\": 167.6,\n" +
" \"address\": {\n" +
" \"streetAddress\": \"21 2nd Street\",\n" +
" \"city\": \"New York\",\n" +
" \"state\": \"NY\",\n" +
" \"postalCode\": \"10021-3100\"\n" +
" },\n" +
" \"phoneNumbers\": [\n" +
" {\n" +
" \"type\": \"home\",\n" +
" \"number\": \"212 555-1234\"\n" +
" },\n" +
" {\n" +
" \"type\": \"office\",\n" +
" \"number\": \"646 555-4567\"\n" +
" }\n" +
" ],\n" +
" \"children\": [],\n" +
" \"spouse\": null\n" +
"}";
// this is a simpler way of declaring and using the JacksonJsonProvider
ObjectMapper objectMapper = new ObjectMapper();
Configuration conf = Configuration.builder()
.jsonProvider(new JacksonJsonProvider(objectMapper))
.build();
Object obj = JsonPath.using(conf).parse(payload).read("$.phoneNumbers");
// prints out:
// [{type=home, number=212 555-1234}, {type=office, number=646 555-4567}]
System.out.println(obj);
// prints out:
// [{"type":"home","number":"212 555-1234"},{"type":"office","number":"646 555-4567"}]
System.out.println(objectMapper.writer().writeValueAsString(obj));
I'm trying to parse below JSON and looking for "zip-code" value "526262". I'm new to Java and struggling to get the zip-code value?
This is my JSON:
{
"id": "6fffdfdf-8d04-4f4e-b746-20930671bd9c",
"timestamp": "2017-07-21T03:51:27.329Z",
"lang": "en",
"result": {
"source": "testsrc",
"resolvedQuery": "testquery",
"action": "test",
"actionIncomplete": true,
"parameters": {
"zip-code": "526262"
}
}
}
And this is my Java code:
String test= "{\n" +
"\t\"id\": \"6fffdfdf-8d04-4f4e-b746-20930671bd9c\",\n" +
"\t\"timestamp\": \"2017-07-21T03:51:27.329Z\",\n" +
"\t\"lang\": \"en\",\n" +
"\t\"result\": {\n" +
"\t\t\"source\": \"testsrc\",\n" +
"\t\t\"resolvedQuery\": \"testquery\",\n" +
"\t\t\"action\": \"test\",\n" +
"\t\t\"actionIncomplete\": true,\n" +
"\t\t\"parameters\": {\n" +
"\t\t\t\"zip-code\": \"526262\"\n" +
"\t\t}\n" +
"\t}\n" +
"}";
JSONObject request = new JSONObject(test);
String zipCode = request.getJSONObject("result").get("parameters").toString();
System.out.println("zipCode is : " + zipCode);
But I'm getting below output:
zipCode is : {"zip-code":"526262"}
How to get zip-code value alone?
Can someone help how to get this value in java?
You should use getJSONObject when getting parameters so that you can keep using the JSONObject API to dig deeper.
request.getJSONObject("result").getJSONObject("parameters").getString("zip-code");
request.getJSONObject("result").get("parameters").getString("zip_code")
will solve your problem. JSON objects are built to handle nesting.
I have a JSON file and need to get the parameter ' fulltext ' , but I'm new to JSON and do not know how to retrieve it in Java . Could someone explain to me how caught this value fulltext ?
Here a piece of the file in JSON.
{
"head": {
"vars": [ "author" , "title" , "paper" , "fulltext" ]
} ,
"results": {
"bindings": [
{
"author": { "type": "uri" , "value": "http://data.linkededucation.org/resource/lak/person/richard-scheines" } ,
"title": { "type": "literal" , "value": "Discovering Prerequisite Relationships among Knowledge Components" } ,
"paper": { "type": "uri" , "value": "http://data.linkededucation.org/resource/lak/conference/edm2014/paper/492" } ,
"fulltext": { "type": "literal" , "value": "GET TEXT" }
} ,
Json library download from here jar dowonload form here
Add this code in JSonParsing.java
import org.json.*;
public class JSonParsing {
public static void main(String[] args){
String source = "{\n" +
" \"head\": {\n" +
" \"vars\": [ \"author\" , \"title\" , \"paper\" , \"fulltext\" ]\n" +
" } ,\n" +
" \"results\": {\n" +
" \"bindings\": [\n" +
" {\n" +
" \"author\": { \"type\": \"uri\" , \"value\": \"http://data.linkededucation.org/resource/lak/person/richard-scheines\" } ,\n" +
" \"title\": { \"type\": \"literal\" , \"value\": \"Discovering Prerequisite Relationships among Knowledge Components\" } ,\n" +
" \"paper\": { \"type\": \"uri\" , \"value\": \"http://data.linkededucation.org/resource/lak/conference/edm2014/paper/492\" } ,\n" +
" \"fulltext\": { \"type\": \"literal\" , \"value\": \"GET TEXT\" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}\n" +
"";
JSONObject main = new JSONObject(source);
JSONObject results = main.getJSONObject("results");
JSONArray bindings = results.getJSONArray("bindings");
JSONObject firstObject = bindings.getJSONObject(0);
JSONObject fulltextOfFirstObject = firstObject.getJSONObject("fulltext");
String type = fulltextOfFirstObject.getString("type");
String value = fulltextOfFirstObject.getString("value");
System.out.println("Type :"+ type+"\nValue :"+value);
}
}
NOTE: In JSON {} represents jsonObject and [] represents jsonArray.
You can use org.json/Jackson to convert this string to JSONObject.
If it is a JSONObject called val;
then val.get("results").get("bindings").get(0).get("fulltext")
will give you the full text of first element of bindings.
There are many good JSON parsing libraries for Java. Try out Org.JSON (Maven) or Jackson Library (Maven) or my personal favorite Google's GSON Library (Maven) that can convert Java Objects into JSON and back.
I recommend you using https://github.com/alibaba/fastjson , It's easy to use.