Say I have a JSON string like:
{"title":"aaa","url":"bbb","image":{"url":"ccc","width":"100","height":"200"}, ...
My accessor:
import com.google.gson.annotations.SerializedName;
public class accessorClass {
#SerializedName("title")
private String title;
#SerializedName("url")
private String url;
#SerializedName("image")
private String image;
// how do I place the sub-arrays for the image here?
...
public final String get_title() {
return this.title;
}
public final String get_url() {
return this.url;
}
public final String get_image() {
return this.image;
}
...
}
And my main:
Gson gson = new Gson();
JsonParser parser = new JsonParser();
JsonArray Jarray = parser.parse(jstring).getAsJsonArray();
ArrayList<accessorClass > aens = new ArrayList<accessorClass >();
for(JsonElement obj : Jarray )
{
accessorClass ens = gson.fromJson( obj , accessorClass .class);
aens.add(ens);
}
What do you think would be the best way to get those sub-arrays for the image here?
FYI if your JSON is an array: {"results:":[{"title":"aaa","url":"bbb","image":{"url":"ccc","width":"100","height":"20...},{}]}
Then you need a wrapper class:
class WebServiceResult {
public List<AccessorClass> results;
}
If your JSON isn't formatted like that, then your For loop you created will do it, (if not a little clunky, would be better if your JSON is formed like above).
Create an Image class
class ImageClass {
private String url;
private int width;
private int height;
// Getters and setters
}
Then change your AccessorClass
#SerializedName("image")
private ImageClass image;
// Getter and setter
Then GSON the incoming String
Gson gson = new Gson();
AccessorClass object = gson.fromJson(result, AccessorClass.class);
Job done.
Related
I'm trying to consume the following API result into a Java object.
The code can be seen below.
public Map<String, List<CurrencyData>> gsonCurrency(String answer) {
Gson g = new Gson();
CurrencyData currencyData = null;
Map<String, List<CurrencyData>> object;
try {
object = g.fromJson(answer,
new TypeToken<Map<String, List<CurrencyData>>>().getType());
} catch (Exception e) {
throw new OutputFromApiException("HistoricalFlight API output is empty ", e.toString());
}
return object;
public class CurrencyData {
#SerializedName("rates")
#Expose
private Rates rates;
#SerializedName("base")
#Expose
private String base;
#SerializedName("date")
#Expose
private String date;
// Getters & Setters
}
I get the following error.
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 11 path $.
Your CurrencyData is not representative of the payload from the API endpoint you are calling. The quickest fix is to change Rates rate to a Map of String currency keys to BigDecimal's. Don't use Double as you will get precision errors.
public static class CurrencyData {
#SerializedName("rates")
#Expose
private Map<String, BigDecimal> rates;
...
}
You are also deserializing the wrong data structure. You only need to deserialize an instance of CurrencyData.
public CurrencyData gsonCurrency(String answer) {
try {
return new Gson().fromJson(answer, CurrencyData.class);
} catch (Exception e) {
throw new OutputFromApiException("HistoricalFlight API output is empty ", e.toString());
}
}
You need to modify your CurrencyData class to look like the following for it to be able to consume your API result.
public final class CurrencyData {
#SerializedName("rates")
private Map<String, BigDecimal> rates = new HashMap<>();
#SerializedName("base")
private String base;
#SerializedName("date")
private String date;
public Map<String, BigDecimal> getRates() {
return rates;
}
public void setRates(Map<String, BigDecimal> rates) {
this.rates = rates;
}
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
Now you can do the following example.
Gson gson = new Gson();
CurrencyData data = new CurrencyData();
data.setBase("USD");
data.setDate("2019-01-01");
Map<String, BigDecimal> ratesMap = new HashMap<>();
ratesMap.put("SEK", new BigDecimal("9.1"));
ratesMap.put("DKK", new BigDecimal("8.2"));
data.setRates(ratesMap);
String json = gson.toJson(data);
System.out.println(json);
Which prints:
{"base":"USD","date":"2019-01-01","rates":{"DKK":8.2,"SEK":9.1}}
You can also reverse the process like so.
CurrencyData parsedData = gson.fromJson(json, CurrencyData.class);
// Prints only the "rates"
System.out.println(parsedData.getRates().toString());
Which prints:
{DKK=8.2, SEK=9.1}
I'm working on a personal project in Android and I want to use GSON to parse a JSON file containing the data I need.
I have a local JSON file with the following structure:
{
"Object1": {
"foo": "value1",
"bar": "value2",
"baz": "value3",
...
},
"Object2": {
"foo": "value4",
"bar": "value5",
"baz": "value6",
...
},
...
}
I have already made an Object class of the following structure:
Class Object {
String data;
...
}
How would I parse this JSON file with this structure?
EDIT: The JSON file I use is very large, it contains about 400+ of these objects of type Object. I would have to iterate over each object to create a new JSONObject, but I do not know how to do this.
In the solution below, we convert the JSON you've provided in your link as a JSONOject. Then we get the list of names contained in the JSON ("Abaddon", "Archeri", ...). Once we have the list we iterate through it. For each name we get the JSON object associated with it.
Then we use GSON to convert each object into a Demon object. The Demon class has been generated using http://www.jsonschema2pojo.org/ as suggested above.
As all the objects in the JSON have the same structure we need only one class to deserialize every single one of them.
Deserializer
public List<Demon> deserialize(String json) {
try {
JSONObject jsonObject = new JSONObject(json);
final JSONArray names = jsonObject.names();
final List<Demon> demons = new ArrayList<>();
final Gson gson = new Gson();
Demon demon;
for (int i = 0; i < names.length(); i++) {
demon = gson.fromJson(jsonObject.get(names.getString(i)).toString(), Demon.class);
demons.add(demon);
}
return demons;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
Demon class
public class Demon {
#SerializedName("ailments")
#Expose
public String ailments;
#SerializedName("align")
#Expose
public String align;
#SerializedName("code")
#Expose
public Integer code;
#SerializedName("inherits")
#Expose
public String inherits;
#SerializedName("lvl")
#Expose
public Integer lvl;
#SerializedName("pcoeff")
#Expose
public Integer pcoeff;
#SerializedName("race")
#Expose
public String race;
#SerializedName("resists")
#Expose
public String resists;
#SerializedName("skills")
#Expose
public List<String> skills = null;
#SerializedName("source")
#Expose
public List<String> source = null;
#SerializedName("stats")
#Expose
public List<Integer> stats = null;
public Demon(){
// Default constructor
}
}
I have singleton implementation of enum as below :
public enum DeviceDetail{
INSTANCE;
private Context context = null;
private int handlercheck = 0;
private String network = "";
private String deviceInfo = "NoData";
private String androidVersion = "";
private String appVersion = "";
private String appName = "";
private String deviceID;
private String deviceinfo;
public void initilize(){
// deviceInfo = getDeviceInfo();
networktype = getNetworktype(context);
deviceID = getDeviceID(context);
//androidVersion = getAndroidVersion();
appVersion = getAppVersion(context);
appName = getAppName(context);
}
DeviceDetail(){
deviceInfo = getDeviceInfo();
androidVersion = getAndroidVersion();
initilize();
}
public static DeviceDetail getInstance() {
return DeviceDetail.INSTANCE;
}
}
I want to convert this DeviceDetail to JSON using GSON, for that I have written
public static String convertObjectToJsonString(DeviceDetail deviceData) {
Gson gson = new Gson();
return gson.toJson(deviceData);
}
I am calling this method as
convertObjectToJsonString(DeviceDetail.INSTANCE)
but it only returns me the string "INSTANCE" not key value pairs as it does for objects. Suggest the changes need to be made so that I get string with all fields in enum in key value JSON.
I have ended up in using a not so elegant workaround as below :
public static String convertObjectToJsonString(DeviceDetail deviceData) {
// Gson gson = new Gson();
// GsonBuilder gb = new GsonBuilder();
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("androidVersion", deviceData.getAndroidVersion());
jsonObject.addProperty("appName", deviceData.getAppName());
jsonObject.addProperty("appVersion", deviceData.getAppVersion());
jsonObject.addProperty("networkType", deviceData.getNetworktype());
jsonObject.addProperty("deviceInfo", deviceData.getDeviceInfo());
jsonObject.addProperty("deviceID", deviceData.getDeviceID());
jsonObject.addProperty("city", deviceData.getCity());
jsonObject.addProperty("country", deviceData.getCountry());
//jsonObject.addProperty("appName",deviceData.getAppName());
return jsonObject.toString();
}
Please i have a json response String like this:
{"result":{"id":21456,"name":"3mm nail","type":"2" }}
and this is my code:
class rootObj{
List<Result> result;
}
public class Result {
#SerializedName("id")
public String idItem;
#SerializedName("name")
public String name;
}
public static void main(String[] args) throws Exception {
Gson gson = new Gson();
Result result = gson.fromJson(json,Result.class);
System.out.println(result.name);
}
But the result is null :(
Thx in advance.
So.. This code is what i was aiming:
class ResultData{
private Result result;
public class Result {
private String id;
private String name;
}
}
...
Gson gson = new Gson();
ResultData resultData = new Gson().fromJson(json, ResultData.class);
System.out.println(resultData.result.id);
System.out.println(resultData.result.name);
Thx to BalusC gave me the idea about it.
Java - Gson parsing nested within nested
In your JSON string your result property is an Object not an Array. So to make it work with your two Java classes (rootObj and Result) you need to add [brackets] around your {braces}
Original
{"result":{"id":21456,"name":"3mm nail","type":"2" }}
New
{"result":[{"id":21456,"name":"3mm nail","type":"2" }]}
This code works for me:
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
public class TestGson {
private static final String NAME = "3mm nail";
#Test
public void testList() {
final String json = "{\"result\":[{\"id\":21456,\"name\":\"" + NAME + "\",\"type\":\"2\" }]}";
Gson gson = new Gson();
ListWrapper wrapper = gson.fromJson(json, ListWrapper.class);
assertEquals(NAME, wrapper.result.get(0).name);
}
static class ListWrapper {
List<Result> result;
}
static class ObjectWrapper {
Result result;
}
static class Result {
#SerializedName("id")
public int idItem;
#SerializedName("name")
public String name;
}
}
refer this ..It explaining how to parse the json without using the GSON
I'm having following class
public class ReturnData {
public ReturnData() {
OperationResult = Result.Failed;
Messages = "An Error Occured";
UpdateAvailable = "0";
ResultData = "";
}
public Result OperationResult;
public String Messages;
public String UpdateAvailable;
public Object ResultData;
}
I'm having json string like,
{"OperationResult":0,"Messages":"","UpdateAvailable":"","ResultData":{"SessionId":"3b44a524-fc2a-499b-a16e-6d96339a6b5b","UserName":"admin","AccoundId":null,"Roles":["Administrator"],"DisplayName":"Admin","Status":3,"Type":1}}
I want to assign this json string to above class.I'm using GSON for assign json string to java object.In normal class i can assign json string to java object. But for this class i couldn't assign directly. Please any one help me,
Now i'm assigning like,
String formatedjsonstring = {json string};
Log.i("FORMAT STRING:",formatedjsonstring);
Gson gson = new Gson();
ReturnData returndata = (ReturnData) gson.fromJson(
formatedjsonstring, ReturnData.class);
You could use JavaJson from sourceforge. You could pass your json string to JsonObject .parse().
Try this
JsonObject json = JsonObject .parse("{\"OperationResult\":0, \"Messages\":\"UpdateAvailable\"");
System.out.println("OperationResult=" + json.get("OperationResult"));
System.out.println("Messages=" + json.get("Messages"));
https://sourceforge.net/projects/javajson/
Since your Java class doesn't resemble your JSON in any way, shape or form ... you're going to have a problem with that.
Problem #1: OperationResult should be an int
Problem #2: You're declared ResultData as an Object ... Java doesn't work like that.
You need your POJO to match the JSON:
public class ReturnData {
public ReturnData() {
OperationResult = Result.Failed;
Messages = "An Error Occured";
UpdateAvailable = "0";
ResultData = "";
}
public int OperationResult;
public String Messages;
public String UpdateAvailable;
public MyResultData ResultData;
}
class MyResultData {
public String SessionId;
public String UserName;
public String AccountId;
public List<String> Roles;
public String DisplayName;
public int Status;
public int Type;
}
ReturnData rd = new Gson().fromJson(jsonString, ReturnData.class);
I'd also consider using Gson's #SerializedName("name") annotation to convert the PascalCase field names in your JSON to camelCase field names in Java.
#SerializedName("OperationResult") public int operationResult;
Try this:
java.lang.reflect.Type type = new TypeToken<ReturnData>(){}.getType();
ReturnData rd = new Gson().fromJson(jsonString, type);