I have an ArrayList that I use within an ArrayAdapter for a ListView. I need to take the items in the list and convert them to a JSONArray to send to an API. I've searched around, but haven't found anything that explains how this might work, any help would be appreciated.
UPDATE - SOLUTION
Here is what I ended up doing to solve the issue.
Object in ArrayList:
public class ListItem {
private long _masterId;
private String _name;
private long _category;
public ListItem(long masterId, String name, long category) {
_masterId = masterId;
_name = name;
_category = category;
}
public JSONObject getJSONObject() {
JSONObject obj = new JSONObject();
try {
obj.put("Id", _masterId);
obj.put("Name", _name);
obj.put("Category", _category);
} catch (JSONException e) {
trace("DefaultListItem.toString JSONException: "+e.getMessage());
}
return obj;
}
}
Here is how I converted it:
ArrayList<ListItem> myCustomList = .... // list filled with objects
JSONArray jsonArray = new JSONArray();
for (int i=0; i < myCustomList.size(); i++) {
jsonArray.put(myCustomList.get(i).getJSONObject());
}
And the output:
[{"Name":"Name 1","Id":0,"Category":"category 1"},{"Name":"Name 2","Id":1,"Category":"category 2"},{"Name":"Name 3","Id":2,"Category":"category 3"}]
If I read the JSONArray constructors correctly, you can build them from any Collection (arrayList is a subclass of Collection) like so:
ArrayList<String> list = new ArrayList<String>();
list.add("foo");
list.add("baar");
JSONArray jsArray = new JSONArray(list);
References:
jsonarray constructor:
http://developer.android.com/reference/org/json/JSONArray.html#JSONArray%28java.util.Collection%29
collection:
http://developer.android.com/reference/java/util/Collection.html
Use Gson library to convert ArrayList to JsonArray.
Gson gson = new GsonBuilder().create();
JsonArray myCustomArray = gson.toJsonTree(myCustomList).getAsJsonArray();
As somebody figures out that the OP wants to convert custom List to org.json.JSONArray not the com.google.gson.JsonArray,the CORRECT answer should be like this:
Gson gson = new Gson();
String listString = gson.toJson(
targetList,
new TypeToken<ArrayList<targetListItem>>() {}.getType());
JSONArray jsonArray = new JSONArray(listString);
public void itemListToJsonConvert(ArrayList<HashMap<String, String>> list) {
JSONObject jResult = new JSONObject();// main object
JSONArray jArray = new JSONArray();// /ItemDetail jsonArray
for (int i = 0; i < list.size(); i++) {
JSONObject jGroup = new JSONObject();// /sub Object
try {
jGroup.put("ItemMasterID", list.get(i).get("ItemMasterID"));
jGroup.put("ID", list.get(i).get("id"));
jGroup.put("Name", list.get(i).get("name"));
jGroup.put("Category", list.get(i).get("category"));
jArray.put(jGroup);
// /itemDetail Name is JsonArray Name
jResult.put("itemDetail", jArray);
return jResult;
} catch (JSONException e) {
e.printStackTrace();
}
}
}
With kotlin and Gson we can do it more easily:
First, add Gson dependency:
implementation "com.squareup.retrofit2:converter-gson:2.3.0"
Create a separate kotlin file, add the following methods
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
fun <T> Gson.convertToJsonString(t: T): String {
return toJson(t).toString()
}
fun <T> Gson.convertToModel(jsonString: String, cls: Class<T>): T? {
return try {
fromJson(jsonString, cls)
} catch (e: Exception) {
null
}
}
inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type)
Note: Do not add declare class, just add these methods, everything will work fine.
Now to call:
create a reference of gson:
val gson=Gson()
To convert array to json string, call:
val jsonString=gson.convertToJsonString(arrayList)
To get array from json string, call:
val arrayList=gson.fromJson<ArrayList<YourModelClassName>>(jsonString)
To convert a model to json string, call:
val jsonString=gson.convertToJsonString(model)
To convert json string to model, call:
val model=gson.convertToModel(jsonString, YourModelClassName::class.java)
Add to your gradle:
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
Convert ArrayList to JsonArray
JsonArray jsonElements = (JsonArray) new Gson().toJsonTree(itemsArrayList);
I know its already answered, but theres a better solution here use this code :
for ( Field f : context.getFields() ) {
if ( f.getType() == String.class ) || ( f.getType() == String.class ) ) {
//DO String To JSON
}
/// And so on...
}
This way you can access variables from class without manually typing them..
Faster and better ..
Hope this helps.
Cheers. :D
Here is a solution with jackson:
You could use the ObjectMapper to receive a JSON String and then convert the string to a JSONArray.
import com.fasterxml.jackson.databind.ObjectMapper;
import org.json.JSONArray;
List<CustomObject> myList = new ArrayList<>();
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(myList);
JSONArray jsonArray = new JSONArray(jsonString);
Improving on OP's answer when there are a lot of fields.
could cut down some code with field enumeration ... ( but know that reflection is slower.)
public JSONObject getJSONObject() {
JSONObject obj = new JSONObject();
Field[] fields = ListItem.class.getDeclaredFields();
for (Field f : fields) {
try {
obj.put(f.getName(), f.get(ListItem.this));
} catch (JSONException | IllegalAccessException e) {
}
}
return obj;
}
Related
This is how my JSON looks like and I have to parse the JSON, how can this be done using GSON
{
"data": {
"a": {
"abc": {
"c": "d"
}
}
}
}
In which "a" is dynamic key which may vary from time to time. I am unable to find a solution right now
Model
public class Model {
private HashMap<String, String> data;
public Model() {
}
}
Convert json string to Hashmap using Gson & prepare data from hashmap
Gson gson = new Gson();
Type typeHashMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String,String> map = gson.fromJson(YOUR_JSON, typeHashMap);
Set<Map.Entry<String, String>> entrySet = data.entrySet();
Iterator iterator = entrySet.iterator ();
for(int j = 0; j < entrySet.size(); j++) {
try {
Map.Entry entry = (Map.Entry) iterator.next();
String key = entry.getKey().toString();
String value = entry.getValue().toString();
//Add it to your list
}
catch(NoSuchElementException e) {
e.printStackTrace();
}
break;
}
I am not sure if internal part abc is known to you or not. If it is known to you then you can surely do it with GSON. You have to create the class for the inner known object as below:
public class ABC {
public C abc;}
Then create the Class for C:
public class C {
public String c;}
Then just pass the ABC class as the hashmap value as below:
public HashMap<String, ABC> a;
My String contains json
result=[{"USER_ID":83,"PROJECT_BY_DETAILS":"An adaptation of a nursery rhyme into a dramatic film"},{"USER_ID":88,"PROJECT_BY_DETAILS":"Test - over ye mountain blue "}]
How to create JSONOBject and JSONarray from this string
I used this code
JSONObject json =new JSONObject(result);
//Get the element that holds the earthquakes ( JSONArray )
JSONArray earthquakes = json.getJSONArray("");
i got error
Error parsing data org.json.JSONException: Value [{"USER_ID":83,"PRO
If it starts with [ its an array, try with:
JSONArray json =new JSONArray(result);
Difference between JSONObject and JSONArray
use this code for your JsonArray:
try {
JSONArray json = new JSONArray(YOUR_JSON_STRING);
for (int i = 0; i < json.length(); i++) {
JSONObject jsonDATA = json.getJSONObject(i);
String jsonid = jsonDATA.getInt("USER_ID");
String jsondetails = jsonDATA.getString("PROJECT_BY_DETAILS");
}
} catch (JSONException e) {
return null;
}
use Gson for you to do that.
That Json response is an array you know it because of the square brackets [].
Create a mapping object (a java class) with field USER_ID and PROJECT_BY_DETAILS.
public class yourClass(){
public String USER_ID;
public String PROJECT_BY_DETAILS;
}
Create a Type array like so.
final Type typeYourObject = new TypeToken>(){}.getType();
define your list private
List yourList;
Using Gson you will convert that array to a List like so
yourList = gson.fromJson(yourJson, typeYourObject);
with that list later you can do whatever you want. Also with Gson convert it back to JsonArray or create a customs JsonObject.
According to my understanding the JSON object looks like this,
{
"RESULT":[
{
"USER_ID":83,
"PROJECT_BY_DETAILS":"An adaptation of a nursery rhyme into a dramatic film"
},
{
"USER_ID":88,
"PROJECT_BY_DETAILS":"Test - over ye mountain blue "
}
]
}
You are converting this to a String and you wish to re-construct the JSON object. The decode function in the android-side would be this,
void jsonDecode(String jsonResponse)
{
try
{
JSONObject jsonRootObject = new JSONObject(jsonResponse);
JSONArray jData = jsonRootObject.getJSONArray("RESULT");
for(int i = 0; i < jData.length(); ++i)
{
JSONObject jObj = jData.getJSONObject(i);
String userID = jObj.optString("USER_ID");
String projectDetails = jObj.optString("PROJECT_BY_DETAILS");
Toast.makeText(context, userID + " -- " + projectDetails,0).show();
}
}
catch(JSONException e)
{
e.printStackTrace();
}
}
I have the following json I want to deserialize:
{
"locations": [{
"id": 17,
"account_id": 11,
"name": "The Haunted Lexington",
"radius": 100
}]
}
(In this particular instance, there's only one Location, but there can be many).
I deserialize this using Gson with the following code:
Gson gson = new GsonBuilder().create();
LocationList ll = gson.fromJson(jsonString, LocationList.class);
I have the following classes defined:
public class Location {
#SerializedName("id")
private long mId;
#SerializedName("account_id")
private long mAccountId;
#SerializedName("name")
private String mName;
#SerializedName("radius")
private int mRadius;
public long getId() {
return mId;
}
public String getName() {
return mName;
}
}
and:
public class LocationList {
#SerializedName("locations")
private List<Location> mLocations;
}
The thing is, I have a bunch of these "dummy" classes that contain a single object that's a list of other objects (e.g. UserList, MessageList, etc...)
What I'd like to do is have the above json parsed somehow so I can skip defining the intermediate class definition of LocationList, like so:
Gson gson = new GsonBuilder().create();
// Use the same json as above, but skip defining the superfluous "LocationList" class
List<Location> ll = gson.fromJson(jsonString, "locations", ArrayList<Location>.class);
Is there a way I can do this, perhaps by providing a custom deserializer?
I faced a similar problem not long ago, and solved it like this
// Parse the JSON response.
JSONArray jsonArray = new JSONArray(response);
List<Location> locations = new ArrayList<Location>();
/*
* Create a Location object for every JSONObject in the response,
* and add it to the list.
*/
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Location location = new Gson().fromJson(jsonObject.toString(),
Location.class);
locations.add(location);
The approach here is to loop over every Location in the locations array in the JSON, extracting them one by one and then adding them to a list.
The JSON I worked with had a list as root object, so you probably can't use this JSONArray jsonArray = new JSONArray(response);. Something like this might better suit your situation
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray locationsJsonArray = jsonObject.get("locations");
I have not tested these last 2 lines, but I think you get the idea.
I hope you can use this to solve your problem.
I'm currently using a simple method to achive your goal:
private static <T> List<T> getList(final String jsonVal, final String listTag, T t) {
try {
JsonObject jsonObject = (JsonObject)(new JsonParser()).parse(jsonVal); // root JsonObject. i.e. "locations"
JsonArray jsonArray = (JsonArray)jsonObject.get(listTag);
Gson gson = new GsonBuilder().create();
List<T> list = gson.fromJson(jsonArray, new TypeToken<List<T>>() {}.getType());
return list;
} catch (Exception e) {
throw new IllegalArgumentException("Unexpected json structure!", e);
}
}
Example usage:
final GsonBuilder gsonBuilder = new GsonBuilder();
final Gson gson = gsonBuilder.create();
String jsonString = "{\"locations\":[{\"id\":17,\"account_id\":11,\"name\":\"The Haunted Lexington\",\"radius\":100}]}";
List<Location> list = getList(jsonString, "locations", new Location());
This method should be used for your orther classes, such as:
List<User> userList = getList(jsonString, "users", new User());
List<Message> messageList = getList(jsonString, "messages", new Message());
I am going to receive either a JSON Object or Array from server, but I have no idea which it will be. I need to work with the JSON, but to do so, I need to know if it is an Object or an Array.
I am working with Android.
Does any one have a good way of doing this?
I found better way to determine:
String data = "{ ... }";
Object json = new JSONTokener(data).nextValue();
if (json instanceof JSONObject)
//you have an object
else if (json instanceof JSONArray)
//you have an array
tokenizer is able to return more types: http://developer.android.com/reference/org/json/JSONTokener.html#nextValue()
There are a couple ways you can do this:
You can check the character at the first position of the String (after trimming away whitespace, as it is allowed in valid JSON). If it is a {, you are dealing with a JSONObject, if it is a [, you are dealing with a JSONArray.
If you are dealing with JSON (an Object), then you can do an instanceof check. yourObject instanceof JSONObject. This will return true if yourObject is a JSONObject. The same applies to JSONArray.
This is the simple solution I'm using on Android:
JSONObject json = new JSONObject(jsonString);
if (json.has("data")) {
JSONObject dataObject = json.optJSONObject("data");
if (dataObject != null) {
//Do things with object.
} else {
JSONArray array = json.optJSONArray("data");
//Do things with array
}
} else {
// Do nothing or throw exception if "data" is a mandatory field
}
Presenting an another way :
if(server_response.trim().charAt(0) == '[') {
Log.e("Response is : " , "JSONArray");
} else if(server_response.trim().charAt(0) == '{') {
Log.e("Response is : " , "JSONObject");
}
Here server_response is a response String coming from server
A more fundamental way of doing this is the following.
JsonArray is inherently a List
JsonObject is inherently a Map
if (object instanceof Map){
JSONObject jsonObject = new JSONObject();
jsonObject.putAll((Map)object);
...
...
}
else if (object instanceof List){
JSONArray jsonArray = new JSONArray();
jsonArray.addAll((List)object);
...
...
}
instanceof
Object.getClass().getName()
For those tackling this issue in JavaScript, the following did the job for me (not sure how efficient it is).
if(object.length != undefined) {
console.log('Array found. Length is : ' + object.length);
} else {
console.log('Object found.');
}
JsonNode jsonNode=mapper.readTree(patchBody);
jsonNode has two method:
isObject();
isArray();
My approach would be a total abstraction from this. Maybe someone finds this useful...
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class SimpleJSONObject extends JSONObject {
private static final String FIELDNAME_NAME_VALUE_PAIRS = "nameValuePairs";
public SimpleJSONObject(String string) throws JSONException {
super(string);
}
public SimpleJSONObject(JSONObject jsonObject) throws JSONException {
super(jsonObject.toString());
}
#Override
public JSONObject getJSONObject(String name) throws JSONException {
final JSONObject jsonObject = super.getJSONObject(name);
return new SimpleJSONObject(jsonObject.toString());
}
#Override
public JSONArray getJSONArray(String name) throws JSONException {
JSONArray jsonArray = null;
try {
final Map<String, Object> map = this.getKeyValueMap();
final Object value = map.get(name);
jsonArray = this.evaluateJSONArray(name, value);
} catch (Exception e) {
throw new RuntimeException(e);
}
return jsonArray;
}
private JSONArray evaluateJSONArray(String name, final Object value) throws JSONException {
JSONArray jsonArray = null;
if (value instanceof JSONArray) {
jsonArray = this.castToJSONArray(value);
} else if (value instanceof JSONObject) {
jsonArray = this.createCollectionWithOneElement(value);
} else {
jsonArray = super.getJSONArray(name);
}
return jsonArray;
}
private JSONArray createCollectionWithOneElement(final Object value) {
final Collection<Object> collection = new ArrayList<Object>();
collection.add(value);
return (JSONArray) new JSONArray(collection);
}
private JSONArray castToJSONArray(final Object value) {
return (JSONArray) value;
}
private Map<String, Object> getKeyValueMap() throws NoSuchFieldException, IllegalAccessException {
final Field declaredField = JSONObject.class.getDeclaredField(FIELDNAME_NAME_VALUE_PAIRS);
declaredField.setAccessible(true);
#SuppressWarnings("unchecked")
final Map<String, Object> map = (Map<String, Object>) declaredField.get(this);
return map;
}
}
And now get rid of this behaviour forever...
...
JSONObject simpleJSONObject = new SimpleJSONObject(jsonObject);
...
how to parse something like this in JSON ?
{"nodes":
{"0":
{"node":{"id":"13970","name_ar":"\u0623\u062f\u0647\u0645","name_en":"Adham","bio_ar":""}},
"1":
{"node":{"id":"14033","name_ar":"aa","name_en":"Ahmed Shaalan","bio_ar":""}}}
Its not an array its more than one object, any help please ?
You can retrieve them using JSONObject. This is a very simple example, and only parses the id out of one node:
JSONObject object = new JSONObject(myJsonString);
JSONObject nodes = object.getJSONObject("nodes");
JSONObject zero = nodes.getJSONObject("0");
JSONObject myNode = zero.getJSONObject("node");
String id myNode = myNode.getString("id");
Android contains native JSON parser - it is good for small amount of data (look into package org.json ) . If you have more data to parse, some pull parser like GSON will be better.
You need to create first a class with all the variables inside the JSON. Something like this:
import java.util.HashMap;
public class NodesClass { // Create a new class called NodesClass
public Nodes nodes; // Create a new public class
public class Nodes {
public HashMap<String, InnerObject> nodes;
}
public class InnerObject {
public Node node;
public class Node {
public int id;
public String name_ar, name_en, bio_ar;
}
}
}
Ant then you need to retrieve the data. E.g something like this:
NodesClass ndes = new Gson().fromJson(stringNodes, NodesClass.class);
int[] id = new int[11];
for (int numNodes = 0; numNodes < maxNumNodes; numNodes++)
{
try {
id[numNodes] = ndes.nodes.get(String.valueOf(numNodes)).node.id;
} catch (NullPointerException n) { break; }
}
I hope it help you.
Use org.json.JSONObject class:
jObject = new JSONObject(jString);
JSONObject nodesObject = jObject.getJSONObject("nodes");
ArrayList<JSONObject> objects = new ArrayList<JSONObject>();
for( int i=0; i<10; i++)
{
objects.add(nodesObject.getJSONObject(""+i);
}
String name = objects.get(0).getJSONObject("node").getString("name_ar");
...