Wicket : pass json to ListView in java - java

List userList = Arrays.asList(
new User[] {
new User("FirstA", "LastA"),
new User("FirstB", "LastB"),
new User("FirstC", "LastC")
});
add(new ListView("listview", userList) {
protected void populateItem(ListItem item) {
User user = (User) item.getModelObject();
item.add(new Label("firstname", user.getFirstname()));
item.add(new Label("lastname", user.getLastname()));
}
});
The above code adds values from List userList and displays Firstname and LastName in Table.
I need to pass JSONObject to ListView.
Json schema -
{"schema":[{"name":"John","id":"01"},{"name":"Sam","id":"02"}]}
Json is passed from Database -
JSONObject json=widget.getJsonForTableContent(query); //QUERY from Database
json.toString();
System.out.println(json); //Prints json - {"schema":[{"name":"John","id":"01"},{"name":"Sam","id":"02"}]}
Iterator<String> iter=json.keys();
while(iter.hasNext())
{
String key = iter.next();
System.out.println(key); //prints only "schema" from json in console
}
The key value prints only "schema" in console.
How to parse and iterate json to print "name" and "id" also and pass these values to ListView to display in wicket Table
I am just a beginner.Any help would be appreciated.Thankyou

Here is standard API for a JSON parser / additional overview with examples
The overview provides an example of using the API to parse JSON from an InputStream:
URL url = new URL("https://graph.facebook.com/search?q=java&type=post");
try (InputStream is = url.openStream();
JsonParser parser = Json.createParser(is)) {
while (parser.hasNext()) {
Event e = parser.next();
if (e == Event.KEY_NAME) {
switch (parser.getString()) {
case "name":
parser.next();
System.out.print(parser.getString());
System.out.print(": ");
break;
case "message":
parser.next();
System.out.println(parser.getString());
System.out.println("---------");
break;
}
}
}
}
Not sure where you'll ultimately be deriving your JSON data from but if you wanted to test it with a static string you could convert the string to an input stream as follows:
InputStream stream = new ByteArrayInputStream(json.toString().getBytes(StandardCharsets.UTF_8));
As for the ListView part of your question - it wouldn't be very difficult once you have parsed out the tokens to add them to the ListView similarly to what you've done.

Related

How to store ArrayList into sharedPreferences in Android

In my application I want store ArrayList into sharedPreferences and get this list in another page!
For store this List i used this library : https://github.com/MrNouri/GoodPrefs
I write below codes, but when get this data I don't know how can get data!
My codes for store list :
for (int i : intList) {
stringBuilder.append("ID : ").append(testPlans.get(i).getId())
.append("Type : ").append(testPlans.get(i).getItemType())
.append("Content").append(steps.get(i).getStepData().toString()).append("-");
App.stepsBodyList.add(new DataItem(testPlans.get(i).getId(),
testPlans.get(i).getItemType(),
steps.get(i).getStepData().toString()));
}
GoodPrefs.getInstance().saveObjectsList(TEST_STEPS_STORED_LIST, App.stepsBodyList);
My codes for get data :
private List<DataItem> storedStepsBodyList = new ArrayList<>();
Toast.makeText(context, ""+
GoodPrefs.getInstance().getObjectsList(TEST_STEPS_STORED_LIST,).size()
, Toast.LENGTH_SHORT).show();
This library for get list give me 2 constructor, one is tag name and second value is default! (TEST_STEPS_STORED_LIST,)
But I don't know can i set default value for second item of constructor!
I write this GoodPrefs.getInstance().getObjectsList(TEST_STEPS_STORED_LIST,storedStepsBodyList) but show me error for this storedStepsBodyList .
How can i fix it?
Simple way, you can use Gson library, add it to build.gradle, it will serialize your list to JSON and save it to SharePreference
implementation 'com.google.code.gson:gson:2.8.6'
public void saveItems(List<Item> items) {
if (items != null && !items.isEmpty()) {
String json = new Gson().toJson(items);
mSharedPreferences.edit().putString("items", json).apply();
}
}
public List<Item> getItems() {
String json = mSharedPreferences.getString("items", "");
if (TextUtils.isEmpty(json)) return Collections.emptyList();
Type type = new TypeToken<List<Item>>() {
}.getType();
List<Item> result = new Gson().fromJson(json, type);
return result;
}

Google Places detail "photos[]" jsonarray is always null

So I get place_id by storing it in a Hashmap with the "name" of the place as the key.
private HashMap<String, String> placeTitleId = new HashMap<>();
if (!place.isNull("place_id")) {
placeId = place.getString("place_id");
placeTitleId.put(name, placeId);
}
Later, I create the Places Detail search url:
private String createPlaceDetailsUrl(String placeId) {
StringBuilder stringBuilder = new StringBuilder("https://maps.googleapis.com/maps/api/place/details/json?");
stringBuilder.append("placeid=").append(placeId);
stringBuilder.append("&key=").append(GOOGLE_PLACES_API_KEY);
return stringBuilder.toString();
}
Finally, I parse the json response:
JSONObject data = new JSONObject(result);
if (data.getString("status").equalsIgnoreCase("OK")) {
JSONArray photoArray = data.getJSONArray("photos");
}
What I don't understand is why the "photos" json array has no value
Android Monitor: W/System.err: org.json.JSONException: No value for photos
The documentation says that the photos[] jsonarray should have up to 10 photos. However, the json output schema does not contain a photos[] object, which I find weird. Is there a problem with how I am obtaining place_id or parsing the response?
EDIT:
The "result" String is incredibly long, but I can provide a gist:
result {
"address components" : [
*bunch of stuff*
]
...
"geometry" : {
*bunch of stuff*
}
"icon"
"id"
"photos" : [
{
"height"
"html_attributions:
"photo_reference!!
}
{
...
"photo_reference!!
}
*bunch more of these*
]
}
EDIT:
Fix is getting json object "result
JSONObject jsonObject = new JSONObject(result);
JSONObject data = new JSONObject("result");
The data object has "pictures"
Try this.
JSONObject data = new JSONObject(result);
// add log here ,make sure you have photos in your result
Log.e("result", result + "");
if (data.getString("status").equalsIgnoreCase("OK")) {
// edited here
JSONArray photoArray = data.optJSONArray("photos");
}
Edit
if (data .has("photos")) {
Log.e("photos", "photos exists");
} else {
Log.e("photos", "photos not exists");
}
Use data .has("photos") in your code and judge it .
Note
Use
JSONObject data = new JSONObject(result);
if(data.has("TAG")){
// if has it in your data,do something
}
to determine whether this tag is present in the data

Java extract from nested JSON

I want to use financial data from yahoo in my program, it already works. I get the complete JSON content and I can display it. But now I want to extract the price as int.
public class Main {
public static void main (String[]args) throws IOException {
String sURL = "http://finance.yahoo.com/webservice/v1/symbols/googl/quote?format=json"; //just a string
// Connect to the URL using java's native library
URL url = new URL(sURL);
HttpURLConnection request = (HttpURLConnection) url.openConnection();
request.connect();
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject(); //may be an array, may be an object.
System.out.print(rootobj);
}
}
EDIT
This is the JSON data from yahoo
{
"list" : {
"meta" : {
"type" : "resource-list",
"start" : 0,
"count" : 1
},
"resources" : [
{
"resource" : {
"classname" : "Quote",
"fields" : {
"name" : "Google Inc.",
"price" : "554.520020",
"symbol" : "GOOGL",
"ts" : "1432324800",
"type" : "equity",
"utctime" : "2015-05-22T20:00:00+0000",
"volume" : "1213288"
}
}
}
]
}
}
EDIT 2
I changed my code
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //convert the input stream to a json element
JsonObject obj = root.getAsJsonObject();
JsonObject result = obj.get("list").getAsJsonObject();
String result2 = result.get("resources").toString();
System.out.print(result2);
And now I already get this
[{"resource":{"classname":"Quote","fields":{"name":"Google Inc.","price":"554.520020","symbol":"GOOGL","ts":"1432324800","type":"equity","utctime":"2015-05-22T20:00:00+0000","volume":"1213288"}}}]
How can I get the "price" now?
EDIT 3
Ok I got it now, it works and I only get the price as double, but is this a smart way to solve this task?
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //convert the input stream to a json element
JsonObject obj = root.getAsJsonObject();
JsonObject result = obj.get("list").getAsJsonObject();
JsonArray result2 = result.get("resources").getAsJsonArray();
JsonObject result3 = result2.get(0).getAsJsonObject();
JsonObject result4 = result3.get("resource").getAsJsonObject();
JsonObject result5 = result4.get("fields").getAsJsonObject();
String result6 = result5.get("price").toString();
result6 = result6.replace("\"", "");
double value = Double.parseDouble(result6);
System.out.print(value);
you should reach "fields" object to extract "name", "price" etc.
The org.json library is easy to use. Example code below: your response as a string :
JSONObject obj1 = new JSONObject(response);
JSONArray arr = obj1.getJSONObject("list").getJSONArray("resources"); //GETS RESOURCES ARRAY
for (int i = 0; i < arr.length(); i++)
{
String resource = arr.getJSONObject(i).toString();
JSONObject obj2 = new JSONObject(resource);
String resourceObject = obj2.getJSONObject("resource").toString(); //RESOURCE OBJECT
JSONObject obj3 = new JSONObject(resourceObject);
String name = obj3.getJSONObject("fields").getString("name"); //REACHED THE FIELDS
float price = (float)obj3.getJSONObject("fields").getDouble("price");
System.out.println(name);
System.out.println(price);
}
Download : http://mvnrepository.com/artifact/org.json/json
He is already using gson.
If you want to continue using gson and know the structure before, you could create classes that stores the data.
class GoogleRequest{
private GoogleList list;
public GoogleList getList() {
return list;
}
public void setList(GoogleList list) {
this.list = list;
}
}
// class for list
class GoogleList{
private Meta meta;
private List<Resources> resources;
public List<Resources> getResources() {
return resources;
}
public void setResources(List<Resources> resources) {
this.resources = resources;
}
public Meta getMeta() {
return meta;
}
public void setMeta(Meta meta) {
this.meta = meta;
}
}
// create other classes here like the Resources class
JsonParser jp = new JsonParser(); // from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream)request.getContent()));
GoogleRequest list = new Gson().fromJson(root,GoogleRequest.class);
The GoogleRequest should hold a List object and a Meta object. gson will introspect and set the properties. gson will set properties to null if they where not introspected. So you could use.
if( list.getResources() != null ){
// list is here
}else{
// do some other code and parse diffrent json
}
If you don't know if it is a array or object create different classes to handle it for you. Just parse the data with new Gson().fromJson();
Now remember that you need right properties for the job. Let's say you have this json in java
String json = "{\"price\" : \"554.520020\"}";
Then price needs to be Double or double. If you use Double you could check
if( obj.getPrice() != null ){
System.out.println( obj.getPrice().intValue() );
}
Note: you will loose precision if you cast double to int

Parsing JSON Data (Android)

Alright. I have a JSON Object sent to me from a server which contains the following data:
{
"result":
[
{"status":"green","type":"data1"},
{"status":"green","type":"data2"},
{"status":"green","type":"data3"}
],
"status":"ok"
}
The data I want to get is the status for the three status values. Data1, data2, and data3 always show up in that order, so I'm now trying to grab the data by index (e.g. data1 = index 0, data2 = index 1, data3 = index 2). How do I do that?
Try following:
String stat1;
String stat2;
String stat3;
JSONObject ret; //contains the original response
//Parse to get the value
try {
stat1 = ret.getJSONArray("results").getJSONObject(0).getString("status");
stat2 = ret.getJSONArray("results").getJSONObject(1).getString("status");
stat3 = ret.getJSONArray("results").getJSONObject(2).getString("status");
} catch (JSONException e1) {
e1.printStackTrace();
}
You would use JSONObject and JSONArray, the entire string is one JSONObject so you would construct one with it.
JSONObject object = new JSONObject(YOUR_STRING_OF_JSON);
Then you can access it with different get methods depending upon your expected type.
JSONArray results = object.getJSONArray("result"); // This is the node name.
String status = object.getString("status");
for (int i = 0; i < results.length(); i++) {
String resultStatus = results.getJSONObject(i).getString("status");
String type = results.getJSONObject(i).getString("type");
Log.w("JSON Result #" + i, "Status: " + resultStatus + " Type: " + type);
}
You need to surround it with a try/catch because JSON access can throw a JSONException.
Try re-factoring via a forEach loop
var testData =
{
"result":
[
{"status":"green","type":"data1"},
{"status":"green","type":"data2"},
{"status":"green","type":"data3"}
],
"status":"ok"
};
var output = new Object;
var resultSet = new Object;
resultSet = testData.result;
resultSet.forEach(function(data)
{
theStatus = data['status'];
theType = data['type']
output[theType] = theStatus;
});
console.log( output['data1'] );
If you've got your models setup to mirror that data set, then you can let GSON (https://code.google.com/p/google-gson/) do a lot of your work for you.
If you want a bit more control, and want to parse the set yourself you can use JSONObject, JSONArray. There's an example of parsing and assembling a json string here: Android create a JSON array of JSON Objects

Getting attributes from JSON code with Jackson Parser

I want to parse a JSON string using Jackson JSON parser. The JSON code which I want to parse contains an array in which there is an object. From this object, I want to extract the text and retweet_count attributes:
[
{
"created_at": "Tue Jan 08 08:19:58 +0000 2013",
"id": 288560667345178600,
"text": "test tweet",
"source": "web",
"truncated": false,
"user": {
"id": 941802900,
"id_str": "941802900",
"location": ""
},
"contributors": null,
"retweet_count": 0,
"favorited": false,
"retweeted": false
}
]
I tried to do it using this code:
JsonFactory f = new JsonFactory();
JsonParser jp = f.createJsonParser(str);
boolean first = true;
while (jp.nextValue() != JsonToken.END_ARRAY) {
Tweet tweet = new Tweet();
while (jp.nextToken() != JsonToken.END_OBJECT) {
String fieldName = jp.getCurrentName();
jp.nextToken();
if (fieldName.equals("text")) {
tweet.setText(jp.getText());
} else if (fieldName.equals("retweet_count")) {
tweet.setRetweetCount(jp.getValueAsLong());
}
}
}
However, I am not getting the expected results. I think that the the problem is that inside the 'tweet' object, I have another 'user' object and when the parser encounters the } of the user object, it thinks that it is the } of the whole tweet object. Can you please tell me how can I resolve this situation?
Is there a particular reason why you try to use Streaming API instead of tree model or data-binding? Latter two could result in much simpler code. For example:
#JsonIgnoreProperties(ignoreUnknown=true) // so we only include ones we care about
public class Tweet {
String text;
int retweet_count;
}
ObjectMapper mapper = new ObjectMapper(); // reusable (please reuse, expensive to create)
Tweet tweet = mapper.readValue(json, Tweet.class);
System.out.println("Tweet with text '"+tweet.text+"', retweet count of "+tweet.retweet_count);
with data-binding. And with tree model:
ObjectNode root = mapper.readTree(json);
String text = root.path("text").getText();
// and so on
You should probably do what StaxMan suggested and model your data correctly in objects, but the fastest way I know to get the data you want is something like the code sample below.
List<Map<String, Object>> val = readValue(json, new TypeReference<List<Map<String, Object>>>() { });
for (Map<String, Object>> map : val) {
String tweet = map.get("text");
Integer retweetCount = map.get("retweet_count");
}
Here is the updated code which would work. You need to consider the user fieldName and parse it separately, so the } of user object would not be considered as the end of the root object
while (jp.nextValue() != JsonToken.END_ARRAY) {
Tweet tweet = new Tweet();
while (jp.nextToken() != JsonToken.END_OBJECT) {
String fieldName = jp.getCurrentName();
jp.nextToken();
if (fieldName.equals("user")) {
//Here the current token in BEGIN_OBJECT
while (jp.nextToken() != JsonToken.END_OBJECT) {
//You can use the user properties here
}
} else if (fieldName.equals("text")) {
tweet.setText(jp.getText());
} else if (fieldName.equals("retweet_count")) {
tweet.setRetweetCount(jp.getValueAsLong());
}
}
}

Categories

Resources