Gson gson = new Gson();
JsonParser parser = new JsonParser();
JsonElement obj = parser.parse(Tempx.getString("GSON_FEED","")).getAsJsonObject();
for(JsonElement jsx: obj) {
MainPojo cse = gson.fromJson(jsx, MainPojo.class);
TweetList.add(cse);
Log.w("F:", "" + TweetList.get(0).getStatuses().get(0).getScreenName());
}
Trying to store JsonObjects into an ArrayList, however I get an error in the line under obj
for(JsonElement jsx: obj)
saying
foreach not applicable to type 'com.google.gson.JsonElement
How to fix this?
you can easily read JSONArray into ArrayList of type class to which JSONArray is representing. Thank is GSON this entire process can be done in a single line of code. as shown bellow.
ArrayList<MyItem> items2 = (new Gson()).fromJson(result,new TypeToken<ArrayList<MyItem>>() {}.getType());
Lets assume you are given with a JSONArray of type MyItem above line of code will convert JSONArray into the ArrayList of type MyItem.
I have written a sample code, that you may get a better picture.
import java.util.ArrayList;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class MyTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<MyItem> items = new ArrayList<>();
for (int i = 0; i < 5; i++) {
MyItem item = new MyItem();
item.setRate("rate_"+i);
item.setSomeCode("some_"+i);
items.add(item);
}
String result = (new Gson()).toJson(items);
System.out.println(""+result);
ArrayList<MyItem> items2 = (new Gson()).fromJson(result,new TypeToken<ArrayList<MyItem>>() {}.getType());
System.out.println(""+items2.size());
}
}
class MyItem {
private String rate;
private String someCode;
public String getRate() {
return rate;
}
public void setRate(String rate) {
this.rate = rate;
}
public String getSomeCode() {
return someCode;
}
public void setSomeCode(String someCode) {
this.someCode = someCode;
}
}
Output
[
{
"rate": "rate_0",
"someCode": "some_0"
},
{
"rate": "rate_1",
"someCode": "some_1"
},
{
"rate": "rate_2",
"someCode": "some_2"
},
{
"rate": "rate_3",
"someCode": "some_3"
},
{
"rate": "rate_4",
"someCode": "some_4"
}
]
this JSONArray is converted into ArrayList of type MyItem
I have also written some answers on this topic which you may want to check for further information on serialization and de-serialization using GSON library
Example_1
Example_2
Example_3
Example_4
Related
I am new to use gson.
I found a lots of tutorial there I can learn of gson but there are using recylerview and model file.
JsonObjectRequest request = new JsonObjectRequest(LoginUrl, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG , String.valueOf(response));
try {
String statusObject = response.getString("status");
String msgObject = response.getString("msg");
if (statusObject.equals("200")) {
JSONArray jsonArray = response.getJSONArray("response");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject managerResponse= jsonArray.getJSONObject(i);
// userIdObject = managerResponse.getString("user_id");
// String nameObject = managerResponse.getString("name");
// String emailObject = managerResponse.getString("email");
// String mobileObject = managerResponse.getString("mobile");
// String postobject = managerResponse.getString("post");
// pojectObject = managerResponse.getString("project");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
}
Here I can get data from jsonrequest using volley but unable to do that same process using volley and gson. Is there any way to use gson?
Thank You.
Update
My JSON Response
{
"status": "200",
"msg": "Successfully",
"response": [
{
"user_id": "1",
"name": "HEMANT OJHA",
"email": "hemguna#gmail.com",
"mobile": "9584919991",
"address1": "C92, PALLAWI NAGAR BABADIYA KALAN",
"user": "admin",
"api_token": "admin"
}
]
}
Generating POJO class from JSON
// Considering your response consists of json objects & json array
// Create a POJO class for your response with the link above
{
"keyOne": 1,
"keyTwo": "Some Value",
"someArray": [{
"key": "Value"
},
{
"key": "Value"
}
]
}
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class ExampleClass {
#SerializedName("keyOne")
#Expose
private int keyOne;
#SerializedName("keyTwo")
#Expose
private String keyTwo;
#SerializedName("someArray")
#Expose
private List<SomeArray> someArray = null;
public int getKeyOne() {
return keyOne;
}
public void setKeyOne(int keyOne) {
this.keyOne = keyOne;
}
public String getKeyTwo() {
return keyTwo;
}
public void setKeyTwo(String keyTwo) {
this.keyTwo = keyTwo;
}
public List<SomeArray> getSomeArray() {
return someArray;
}
public void setSomeArray(List<SomeArray> someArray) {
this.someArray = someArray;
}
}
// Parsing JSON response with GSON
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
ExampleClass resultObj = gson.fromJson(jsonObject.toString(), ExampleClass.class);
int keyOneValue = resultObj.getKeyOne() // First JSON Object
// Getting String value
String keyTwoValue = resultObj.getKeyTwo() // Second JSON Object
List<SomeArray> yourJSONArray = resultObj.getSomeArray() // Getting JSON Array contents
// Depending on JSON response that you've updated in your question
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
ExampleClass resultObj = gson.fromJson(jsonObject.toString(),ExampleClass.class);
String status = resultObj.getStatus();
String msg = resultObj.getMsg();
List<Response> responseList = resultObj.getResponse();
The best way to use for entire app is create a Utils class and use it for conversion.
GsonUtils.java
// This Class is useful for mapping Json into Java Objects and vice versa.
public class GsonUtils {
private static final Gson gson = new Gson();
// This will Convert Java Objects into JSON String...
public static String toGson(Object object) {
return gson.toJson(object);
}
// Gives Java Objects from JSON
public static <T> T fromGson(String json, Class<T> type) {
return gson.fromJson(json, type);
}
public static JsonArray fromGson(String json) {
return new JsonParser().parse(json).getAsJsonArray();
}
}
Now convert any json to and from POJO via,
POJO pojoObj = GsonUtils.toGson(POJO.class);
Try this
JSON response
String str = new Gson().toJson(response)
I like to know how I might do the following:
I want to create a json format of the following:
I want to be able to create a recursive function that takes an object holding a list of other objects of the same type and in a method to recursively create the format below.
{
"name": "lib",
"contains": [{
"name": "room",
"contains": [{
"name": "bookshelf",
"contains": [{
"name": "shelf",
"contains": []
}]
}]
}]
}
I have this as the following method:
private JSONObject json = new JSONObject();
public JSONObject setupLib(Contains contain) {
int count = contain.getContainerList().size();
for(int i = 0; i < count; i++){
try {
json.put("name", contain.getContainerList().get(i).getContainerName());
if(contain.getContainerList().size() != 0) {
Contains contains = (Contains) contain.getContainerList().get(i);
JSONArray array = new JSONArray();
json.put("contain",array.put(setupLib(contains)));}
}catch (JSONException e){
Log.i(Tag, e.getMessage());
}
}
return json;
}
I get a stackoverflow on the array/object
Two options
Do it yourself recursively
Use a library such as Gson to save you the development time and effort
Since this is a learning experience, I have shown both that return this JSON.
{
"name": "lib",
"contains": [{
"name": "room",
"contains": [{
"name": "bookshelf",
"contains": [{
"name": "shelf",
"contains": []
}]
}]
}]
}
public static void main(String[] args) {
Contains lib = new Contains("lib");
Contains room = new Contains("room");
Contains bookshelf = new Contains("bookshelf");
Contains shelf = new Contains("shelf");
bookshelf.add(shelf);
room.add(bookshelf);
lib.add(room);
// Option 1
System.out.println(setupLib(lib).toJSONString());
// Option 2
Gson gson = new Gson();
System.out.println(gson.toJson(lib));
}
private static JSONObject setupLib(Contains contain) {
if (contain == null) return null;
LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
JSONArray array = new JSONArray();
for (Contains c : contain.getContainerList()) {
JSONObject innerContain = setupLib(c);
if (innerContain != null) {
array.add(innerContain);
}
}
map.put("name", contain.getName());
map.put("contains", array);
return new JSONObject(map);
}
This is the model object, for reference
public class Contains {
#SerializedName("name")
#Expose
private String name;
#SerializedName("contains")
#Expose
private List<Contains> contains;
public Contains(String name) {
this.name = name;
contains = new ArrayList<Contains>();
}
public void setName(String name) {
this.name = name;
}
public void add(Contains c) {
this.contains.add(c);
}
public void setContainerList(List<Contains> contains) {
this.contains = contains;
}
public String getName() {
return name;
}
public List<Contains> getContainerList() {
return this.contains;
}
}
I think is far easier if you'd serialize both the JSONObject and Contains classes. This way you'll be able to use the Jackson library to create the JSON file for you.
You can find more information about the Jackson library on the following GitHub page: https://github.com/FasterXML/jackson.
This question already has answers here:
How to parse a dynamic JSON key in a Nested JSON result?
(5 answers)
Closed 7 years ago.
I have been looking for parsing JSON data in java/android. unfortunately, there is no JSON that same as mine. i have JSON data that include weird number, looks like :
{
"formules": [{"1":
{
"formule": "Linear Motion",
"url": "qp1"
},"2":
{
"formule": "Constant Acceleration Motion",
"url": "qp2"
},"3":
{
"formule": "Projectile Motion",
"url": "qp3"
}
}
]
}
Please help me how to parse this in Java/android. Thanks
try this
JSONObject jsonObject = new JSONObject(string);
JSONArray jsonArray = jsonObject.getJSONArray("formules");
JSONObject jsonObject1 = jsonArray.getJSONObject(0);
Now you can access object "1" as
JSONObject json = jsonObject1.getJSONObject("1");
or use iterator to iterate as below
Iterator keys = jsonObject1.keys();
while(keys.hasNext()) {
// loop to get the dynamic key
String currentDynamicKey = (String)keys.next();
JSONObject json = jsonObject1.getJSONObject(currentDynamicKey);
}
let me know if it works
For parsing Json in Android, I have found the Gson Library to be helpful
http://mvnrepository.com/artifact/com.google.code.gson/gson/2.3
What it would require is creating a pojo class that represents your object. Might look something like
public class ClassPojo
{
private Formules[] formules;
public Formules[] getFormules ()
{
return formules;
}
public void setFormules (Formules[] formules)
{
this.formules = formules;
}
#Override
public String toString()
{
return "ClassPojo [formules = "+formules+"]";
}
}
public class Formules
{
private Formule 3;
private Forumle 2;
private Formule 1;
}
public class Formule
{
private String formule;
private String url;
public String getFormule ()
{
return formule;
}
public void setFormule (String formule)
{
this.formule = formule;
}
public String getUrl ()
{
return url;
}
public void setUrl (String url)
{
this.url = url;
}
#Override
public String toString()
{
return "ClassPojo [formule = "+formule+", url = "+url+"]";
}
}
then to convert it to and from JSon,you could use
//Convert to JSON
ClassPojo pojo = new ClassPojo();
Gson gson = new Gson();
String json = gson.toJson(pojo);
//COnvert back to Java object
ClassPojo pojo = gson.fromJson(json,ClassPojo.class);
I want to copy JSON fields from one file to another but only after the field satisfies a particular condition, as for example
{"dataset":
[
{"album_id":1,
"album_type":"Live Performance",
"artist_name":"John Doe",....
}
]
}
I want to copy only those records which have a user given artist_name or any other property, else skip the tuple for copying. I am using the following code to add the filtered records to a JSONObject "wr" which I then write to my output file. But its not giving me the desired results
public static void dumpJSONElement(JsonElement element) {
if (element.isJsonObject()) {
JsonObject obj = element.getAsJsonObject();
java.util.Set<java.util.Map.Entry<String,JsonElement>> entries = obj.entrySet();
java.util.Iterator<java.util.Map.Entry<String,JsonElement>> iter = entries.iterator();
while (iter.hasNext()) {
java.util.Map.Entry<String,JsonElement> entry = iter.next();
if(entry.getKey().equals(filterKey)){
if(! entry.getValue().toString().replace("\"", "").equals(filterValue)){
wr.put(entry.getKey(), entry.getValue());
}
}
else{
wr.put(entry.getKey(), entry.getValue());
}
dumpJSONElement(entry.getValue());
}
} else if (element.isJsonArray()) {
JsonArray array = element.getAsJsonArray();
java.util.Iterator<JsonElement> iter = array.iterator();
while (iter.hasNext()) {
JsonElement entry = iter.next();
dumpJSONElement(entry);
}
} else if (element.isJsonPrimitive()) {
JsonPrimitive value = element.getAsJsonPrimitive();
} else if (element.isJsonNull()) {
} else {
System.out.println("Error. Unknown type of element");
}
}
use code below code to convert your json string to generic java type List<Map<Object, Object>>, use code below.
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class Test {
public static void main(String... args) {
String str = "[{'id':1,'name':'yogesh'},{'id':2,'name':'aarush', 'degree': 'MCA'}]";
Type type = new TypeToken<List<Map<Object, Object>>>() {
}.getType();
List<Map<Object, Object>> list = new Gson().fromJson(str, type);
System.out.println(new Gson().toJson(list));
filterList(list, "name", "yogesh");
System.out.println(new Gson().toJson(list));
}
public static void filterList(List<Map<Object, Object>> list, String key, Object value) {
for (Map<Object, Object> map : list) {
if (map.containsKey(key)) {
if (map.get(key).equals(value)) {
list.remove(map);
}
}
}
}
}
here i filterd name=yogesh record.
output:
[{"id":1.0,"name":"yogesh"},{"id":2.0,"name":"aarush","degree":"MCA"}]
[{"id":2.0,"name":"aarush","degree":"MCA"}]
I had similar issues and I googled, read a lot about this. In conclusion, the best(most efficient) way (with gson) is to write a custom TypeAdapter for your case.
You can test sample code below (it is working as you expected):
public static void answer() {
String jsonAsText = "{\"dataset\":[{\"album_id\":1,\"album_type\":\"Live Performance\",\"artist_name\":\"John Doe\"},{\"album_id\":2,\"album_type\":\"A Dummy Performance\"}]}";
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(List.class, new AlbumInfoListTypeAdapter());
Gson gson = gsonBuilder.create();
List<AlbumInfo> dataSet = gson.fromJson(jsonAsText, List.class);
System.out.println(gson.toJson(dataSet));
}
private static class AlbumInfo {
int album_id;
String album_type;
String artist_name;
}
private static class AlbumInfoListTypeAdapter extends
TypeAdapter<List<AlbumInfo>> {
#Override
public List<AlbumInfo> read(com.google.gson.stream.JsonReader in)
throws IOException {
List<AlbumInfo> dataSet = new ArrayList<AlbumInfo>();
in.beginObject();
while (in.hasNext()) {
if ("dataset".equals(in.nextName())) {
in.beginArray();
while (in.hasNext()) {
in.beginObject();
AlbumInfo albumInfo = new AlbumInfo();
while (in.hasNext()) {
String jsonTag = in.nextName();
if ("album_id".equals(jsonTag)) {
albumInfo.album_id = in.nextInt();
} else if ("album_type".equals(jsonTag)) {
albumInfo.album_type = in.nextString();
} else if ("artist_name".equals(jsonTag)) {
albumInfo.artist_name = in.nextString();
}
}
in.endObject();
if (albumInfo.artist_name != null && !"".equals(albumInfo.artist_name.trim())) {
dataSet.add(albumInfo);
} else {
System.out.println("Album info ignored because it has no artist_name value");
}
}
in.endArray();
}
}
in.endObject();
return dataSet;
}
#Override
public void write(com.google.gson.stream.JsonWriter out,
List<AlbumInfo> dataSet) throws IOException {
out.beginObject();
out.name("dataset").beginArray();
for (final AlbumInfo albumInfo : dataSet) {
out.beginObject();
out.name("album_id").value(albumInfo.album_id);
out.name("album_type").value(albumInfo.album_type);
out.name("artist_name").value(albumInfo.artist_name);
out.endObject();
}
out.endArray();
out.endObject();
}
}
You can modify the read and the write methods. Gson has many cool functions. I strongly suggest you to read samples at this link.
Edit:
Incoming json text:
{
"dataset": [
{
"album_id": 1,
"album_type": "Live Performance",
"artist_name": "John Doe"
},
{
"album_id": 2,
"album_type": "A Dummy Performance"
}
]
}
The output at System.out.println at answer method:
[
{
"artist_name": "John Doe",
"album_type": "Live Performance",
"album_id": 1
}
]
I'm in trouble with Retrofit and a ugly json object in the Trakt.tv API:
{
"season": 1,
"episodes": {
"1": true,
"2": true,
"3": false,
"4": false,
"5": false,
"6": false,
"7": false
}
}
"episodes" content is obviously dynamic and I'd like to handle it as a simple Boolean array, like this:
int season;
Boolean[] episodes;
How to do that?
You can first convert the JSON string into Map<String,Object> then finally create the desired object.
sample code:
public class EpisodesDetail {
private int season;
private Boolean[] episodes;
// getter & setter
}
...
BufferedReader reader = new BufferedReader(new FileReader(new File("json.txt")));
Type type = new TypeToken<Map<String, Object>>() {}.getType();
Map<String, Object> map = new Gson().fromJson(reader, type);
EpisodesDetail geometry = new EpisodesDetail();
geometry.setSeason(((Double) map.get("season")).intValue());
geometry.setEpisodes(((Map<String, Boolean>) map.get("episodes")).values().toArray(
new Boolean[] {}));
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(geometry));
output:
{
"season": 1,
"episodes": [
true,
true,
false,
false,
false,
false,
false
]
}
There is one more approach using GSON Deserialiser
sample code:
class EpisodesDetailDeserializer implements JsonDeserializer<EpisodesDetail> {
#Override
public EpisodesDetail deserialize(final JsonElement json, final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
EpisodesDetail geometry = new EpisodesDetail();
JsonObject jsonObject = json.getAsJsonObject();
int season = jsonObject.get("season").getAsInt();
geometry.setSeason(season);
List<Boolean> episodes = new ArrayList<Boolean>();
Set<Entry<String, JsonElement>> set = jsonObject.get("episodes").getAsJsonObject()
.entrySet();
Iterator<Entry<String, JsonElement>> it = set.iterator();
while (it.hasNext()) {
episodes.add(it.next().getValue().getAsBoolean());
}
geometry.setEpisodes(episodes.toArray(new Boolean[] {}));
return geometry;
}
}
BufferedReader reader = new BufferedReader(new FileReader(new File("json.txt")));
EpisodesDetail episodesDetail = new GsonBuilder()
.registerTypeAdapter(EpisodesDetail.class, new EpisodesDetailDeserializer())
.create().fromJson(reader, EpisodesDetail.class);
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(episodesDetail));
See How do I write a custom JSON deserializer for Gson?
When I use jackson library to parse that JSON, I use ObjectMapper and DramaInfo class as follows.
package jackson;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.ObjectMapper;
class DramaInfo {
int season;
List<Boolean> episodes;
public void setSeason(int season) {
this.season = season;
}
public int getSeason() {
return this.season;
}
public List<Boolean> getEpisodes() {
return new LinkedList<>( this.episodes );
}
public void setEpisodes(Map<String, Boolean> o) {
// used Java 1.8 Stream.
// just see http://docs.oracle.com/javase/tutorial/collections/streams/reduction.html
episodes = o.keySet().stream().map(e -> o.get(e)).collect(Collectors.toList());
}
public String toString() {
String ret = "season: " + this.season + "\n";
ret += this.episodes.toString();
return ret;
}
}
public class LoadJsonData {
public static void main(String[] args) {
String toConvert = "{\"season\": 1, \"episodes\": { \"1\": true, \"2\": true, \"3\": false, \"4\": false, \"5\": false, \"6\": false, \"7\": false } }";
ObjectMapper mapper = new ObjectMapper();
try {
DramaInfo info = mapper.readValue(toConvert, DramaInfo.class);
System.out.println(info);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
So, this is a suggestion because I have never used Retrofit. If you are to use Retrofit as follows, how about trying out the DramaInfo class shown above?
public interface DramaService {
#GET("/dramas/{drama}/info")
DramaInfo listRepos(#Path("drama") String drama);
}