i would like to parse this json but im not able to do it. Heres the Json Structure:
For example: I would like to get String product type => Car
this Code doesnt work:
JSONObject mainData = response.getJSONObject("decode");
String productType = mainData.getString("Product Type");
Please help
decode is an array not an object so it should be
JSONArray mainData = response.getJSONArray("decode");
And then you can get inside objects using the index.
JSONObject jsonObj = mainData.getJSONObject(0);
String answer = jsonObj.getString("label"); //Make
You can try to use Gson
Define your class with something like that
public class YourClass implements Parcelable {
private int price;
#SerializedName("price_currency")
private String priceCurrency;
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getPriceCurrency() {
return priceCurrency;
}
public void setPriceCurrency(String priceCurrency) {
this.priceCurrency = priceCurrency;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(this.price);
dest.writeString(this.priceCurrency);
}
public YourClass() {
}
protected YourClass(Parcel in) {
super(in);
this.price = in.readInt();
this.priceCurrency = in.readString();
}
public static final Creator<YourClass> CREATOR = new Creator<YourClass>() {
#Override
public Pessoa createFromParcel(Parcel source) {
return new YourClass(source);
}
#Override
public YourClass[] newArray(int size) {
return new YourClass[size];
}
};
}
and try to convert your json with something like this
Gson gson = new Gson();
YourClass yourClass = gson.fromJson(yourJson, YourClass.class);
If you really want to do this correctly, you'll need a custom JsonDeserializer. Like this:
public class CarDeserializer implements JsonDeserializer<Car> {
#Override
public Car deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Car car = new Gson().fromJson(json.toString(), Car.class);
try {
JSONObject object = new JSONObject(json.toString());
car.setCurrency(Currency.getInstance(object.getString("price_currency")));
car.setBalance(object.getJSONObject("balance").getInt("API Decode"));
JSONArray decodeArray = object.getJSONArray("decode");
for (int i = 0; i < decodeArray.length(); i++){
JSONObject decodeObject = (JSONObject) decodeArray.get(i);
if (decodeObject.get("label").equals("Make")){
car.setMake(decodeObject.getString("value"));
} else if (decodeObject.get("label").equals("Manufacturer")){
car.setManufacturer(decodeObject.getString("value"));
} else if (decodeObject.get("label").equals("Plant Country")){
car.setPlantCountry(decodeObject.getString("value"));
} else if (decodeObject.get("label").equals("Product Type")){
car.setProductType(decodeObject.getString("value"));
}
}
} catch (JSONException e){
Log.e("CarDeserializer", e.toString(), e);
}
return car;
}
}
The Car object looks like this:
public class Car {
private int price;
private transient Currency currency;
private transient int balance;
private transient String make;
private transient String manufacturer;
private transient String plantCountry;
private transient String productType;
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public Currency getCurrency() {
return currency;
}
public void setCurrency(Currency currency) {
this.currency = currency;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getPlantCountry() {
return plantCountry;
}
public void setPlantCountry(String plantCountry) {
this.plantCountry = plantCountry;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
}
If Currency doesn't work for you, you can change that one to a String type like this:
#SerializedName("price_currency") private String currency;
And change the getter and setter accordingly.
If you have more objects in the decode array. You can add them as more branches in the deserializer.
This is used like this:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Car.class, new CarDeserializer());
Gson gson = gsonBuilder.create();
gson.fromJson(myJsonString, Car.class);
Note: The transient keyword in the Car class indicates to Gson that it shouldn't attempt to automatically parse the json for those fields.
Note 2: You'll need to include Gson in your project if you haven't already added it.
Related
I got a free api for currency tracking with json:
api.coinmarketcap
I need deserialize this json to my compound java object with Gson library. This my model object:
public class Quote {
#SerializedName("quotes")
private String mName;
#SerializedName("price")
private double mPrice;
public Quote(String name, double price) {
mName = name;
mPrice = price;
}
public String getName() {
return mName;
}
public double getPrice() {
return mPrice;
}
}
and:
public class Currency {
private int mId;
private String mSymbol;
private byte mRank;
private String mWebsiteSlug;
private int mMaxSupply;
private Quote mQuote;
public Currency(int id, String symbol, byte rank, String websiteSlug, int maxSupply) {
mId = id;
mSymbol = symbol;
mRank = rank;
mWebsiteSlug = websiteSlug;
mMaxSupply = maxSupply;
}
public int getId() {
return mId;
}
public String getSymbol() {
return mSymbol;
}
public byte getRank() {
return mRank;
}
public String getWebsiteSlug() {
return mWebsiteSlug;
}
public int getMaxSupply() {
return mMaxSupply;
}
public Quote getQuote() {
return mQuote;
}
}
I can not deserialize with such nesting.
You can use enter link description here to create your pojo classes from json
I create currency deserializer:
public class CurrencyDeserializer implements JsonDeserializer<Currency> {
#Override
public Currency deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Currency currency = new Currency();
JsonObject currencyObject = json.getAsJsonObject();
JsonElement id = currencyObject.get("id");
if(!id.isJsonNull()) {
currency.setId(id.getAsInt());
}
JsonElement name = currencyObject.get("name");
if(!name.isJsonNull()) {
currency.setName(name.getAsString());
}
JsonElement symbol = currencyObject.get("symbol");
if(!symbol.isJsonNull()) {
currency.setSymbol(symbol.getAsString());
}
JsonElement slug = currencyObject.get("website_slug");
if(!slug.isJsonNull()) {
currency.setWebsiteSlug(slug.getAsString());
}
JsonElement rank = currencyObject.get("rank");
if(!rank.isJsonNull()) {
currency.setRank(rank.getAsLong());
}
JsonElement circulatingSupply = currencyObject.get("circulating_supply");
if(!circulatingSupply.isJsonNull()) {
currency.setCirculatingSupply(circulatingSupply.getAsLong());
}
JsonElement totalSupply = currencyObject.get("total_supply");
if(!totalSupply.isJsonNull()) {
currency.setTotalSupply(totalSupply.getAsLong());
}
JsonElement maxSupply = currencyObject.get("max_supply");
if(!maxSupply.isJsonNull()) {
currency.setMaxSupply(maxSupply.getAsLong());
}
JsonElement lastUpdated = currencyObject.get("last_updated");
if(!lastUpdated.isJsonNull()) {
Long l = lastUpdated.getAsLong() * 1000;
currency.setLastUpdated(new Date(l));
}
JsonObject quotes = currencyObject.get("quotes").getAsJsonObject();
for(Map.Entry<String, JsonElement> rootObj : quotes.entrySet())
{
Quote quote = context.deserialize(rootObj.getValue(), Quote.class);
quote.setName(rootObj.getKey());
currency.addQuote(quote);
}
return currency;
}
}
Simple and work
in this case, i want to show Json to an response page in java hibernate, query method from DAO like this:
public List<TransactionQR> getAllTransaction() throws HibernateException {
return this.session.createQuery("FROM TransactionQR tr, Batch b, Terminal t, User_Smartphone us, Merchant mc WHERE tr.batch = b.id AND b.user_smartphone = us.id AND b.terminal = t.id AND t.merchant = mc.id AND state = '1' ").list();
}
then in servlet class i try to convert the list into json using Json object and json array then write in response like this:
int start = 0;
String jsonResult = null;
JSONObject jo=new JSONObject();
HttpServletRequest request = context.getRequest();
HttpServletResponse response = context.getResponse();
HttpSession session = context.getSession();
DB db = getDB(context);
//JSONObject jo = new JSONObject();
QRTransactionDao QR = new QRTransactionDao(db);
//Gson objGson = new GsonBuilder().setPrettyPrinting().create();
//String json = objGson.toJson(QR.getAllTransaction());
//System.out.println(json);
List<TransactionQR> str = QR.getAllTransaction();
JSONArray array = new JSONArray();
for(TransactionQR tr : str){
JSONObject str3 = new JSONObject();
str3.put("amount", tr.getAmount());
context.put("jsoncontent", jsonResult);
array.add(str3);
}
jo.put("status", "ok");
jo.put("dataqr", array);
jsonResult=jo.toString();
response.setContentType("application/json");
response.getWriter().print(jsonResult);
but i got the error on syntax in this line loop:
for(TransactionQR tr : str){
the error like this:
[Ljava.lang.Object; cannot be cast to Transaction
here the model Transaction:
package id.co.keriss.consolidate.ee;
import java.io.Serializable;
import java.util.Date;
public class TransactionQR implements Serializable{
private Long id;
private String codeqr;
private Date approvaltime;
private String merchant;
private String code_merchant;
private Long amount;
private Long saldoawal;
private Integer tracenumber;
private String state;
private Date createdate;
private Batch batch;
public TransactionQR() {
}
public TransactionQR(Long id, String codeqr, Date approvaltime, String merchant, String code_merchant, Long amount,
Long saldoawal, Integer tracenumber, String state, Date createdate, Batch batch) {
super();
this.id = id;
this.codeqr = codeqr;
this.approvaltime = approvaltime;
this.merchant = merchant;
this.code_merchant = code_merchant;
this.amount = amount;
this.saldoawal = saldoawal;
this.tracenumber = tracenumber;
this.state = state;
this.createdate = createdate;
this.batch = batch;
}
public Long getId() {
return id;
}
public Date getApprovalTime() {
return approvaltime;
}
public Batch getBatch() {
return batch;
}
public void setBatch(Batch batch) {
this.batch = batch;
}
public void setApprovalTime(Date approvalTime) {
this.approvaltime = approvalTime;
}
public void setId(Long id) {
this.id = id;
}
public Date getApprovaltime() {
return approvaltime;
}
public void setApprovaltime(Date approvaltime) {
this.approvaltime = approvaltime;
}
public String getCodeqr() {
return codeqr;
}
public void setCodeqr(String codeqr) {
this.codeqr = codeqr;
}
public String getMerchant() {
return merchant;
}
public void setMerchant(String merchant) {
this.merchant = merchant;
}
public String getCode_merchant() {
return code_merchant;
}
public void setCode_merchant(String code_merchant) {
this.code_merchant = code_merchant;
}
public Long getAmount() {
return amount;
}
public void setAmount(Long amount) {
this.amount = amount;
}
public Long getSaldoawal() {
return saldoawal;
}
public void setSaldoawal(Long saldoawal) {
this.saldoawal = saldoawal;
}
public Integer getTracenumber() {
return tracenumber;
}
public void setTracenumber(Integer tracenumber) {
this.tracenumber = tracenumber;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Date getCreatedate() {
return createdate;
}
public void setCreatedate(Date createdate) {
this.createdate = createdate;
}
}
i have try to handle the list with Gson:
Gson objGson = new GsonBuilder().setPrettyPrinting().create();
String json = objGson.toJson(QR.getAllTransaction());
System.out.println(json);
in that way, it's work to show but it's not from POJO right i want work with pojo to parse the data to json ?
why i get the error can't cast to model ? any clue ?
Try adding Select tr to your query in getAllTransaction()
Wich is the relation between QRTransactionDao and TransactionQR ?
I am referring to this example here to serialize my object.
I have this initially and it works.
public class MyClass implements Serializable {
private String mediaitem_id;
private String customer_id;
private int quantity;
public MyClass(String item, String customer, int quantity){
this.mediaitem_id = item;
this.customer_id = customer;
this.quantity = quantity;
}
public String toJson(){
ObjectMapper mapper = new ObjectMapper();
try{
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE);
return mapper.writeValueAsString(this);
}catch(Exception ex){
log.error("Error converting MyClass to json " + this, ex);
}
return "";
}
}
MyClass myClass = new MyClass("1234", "23234", 5);
myClass.toJson() gives the below, which is what I want:
{ mediaitem_id: '1234', customer_id: '23234', quantity: 5 }
But now I need to add an arraylist to the class and need to serialise it as well, so I add a new class Account:
public static class Account implements Serializable {
public String accountname;
public String accountid;
public Account(String accountname, String accountid) {
this.accountname = accountname;
this.accountid = accountid;
}
}
public class MyClass implements Serializable {
private String mediaitem_id;
private String customer_id;
private int quantity;
private List<Account> accounts = new ArrayList<>();
public MyClass(String item, String customer, int quantity){
this.mediaitem_id = item;
this.customer_id = customer;
this.quantity = quantity;
}
public void addAccount(String accountname, String accountid) {
Account anAccount = new Account(accountname, accountid);
accounts.add(anAccount);
}
public String toJson(){
ObjectMapper mapper = new ObjectMapper();
try{
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE);
return mapper.writeValueAsString(this);
}catch(Exception ex){
log.error("Error converting MyClass to json " + this, ex);
}
return "";
}
}
MyClass myClass = new MyClass("1234", "23234", 5);
myClass.addAccount("acc-01", "a001");
myClass.addAccount("acc-02", "a002");
myClass.toJson() still gives the same:
{ mediaitem_id: '1234', customer_id: '23234', quantity: 5 }
What am I missing now?
I wanted to get something like:
{ mediaitem_id: '1234', customer_id: '23234', quantity: 5, accounts: [{accountname: 'acc-01', accountid: 'a001'}, {accountname: 'acc-02', accountid: 'a002'}]}
I recommed add your getter and setter for all property in your MyClass .
public String getMediaitem_id() {
return mediaitem_id;
}
public void setMediaitem_id(String mediaitem_id) {
this.mediaitem_id = mediaitem_id;
}
public String getCustomer_id() {
return customer_id;
}
public void setCustomer_id(String customer_id) {
this.customer_id = customer_id;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
I'm trying to store a coordnates (array of double) using Realm-java,but I'm not able to do it.
Here is an example of json that I'm trying to parse:
{"_id":"597cd98b3af0b6315576d717",
"comarca":"string",
"font":null,
"imatge":"string",
"location":{
"coordinates":[41.64642,1.1393],
"type":"Point"
},
"marca":"string",
"municipi":"string",
"publisher":"string",
"recursurl":"string",
"tematica":"string",
"titol":"string"
}
My global object code is like that
public class Images extends RealmObject implements Serializable {
#PrimaryKey
private String _id;
private String recursurl;
private String titol;
private String municipi;
private String comarca;
private String marca;
private String imatge;
#Nullable
private Location location;
private String tematica;
private String font;
private String parentRoute;
public Location getLocation() {return location;}
public void setLocation(Location location) {this.location = location;}
public String getParentRoute() {
return parentRoute;
}
public void setParentRoute(String parentRoute) {
this.parentRoute = parentRoute;
}
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getFont() {
return font;
}
public void setFont(String font) {
this.font = font;
}
public String getRecursurl() {
return recursurl;
}
public void setRecursurl(String recursurl) {
this.recursurl = recursurl;
}
public String getTitol() {
return titol;
}
public void setTitol(String titol) {
this.titol = titol;
}
public String getMunicipi() {
return municipi;
}
public void setMunicipi(String municipi) {
this.municipi = municipi;
}
public String getComarca() {
return comarca;
}
public void setComarca(String comarca) {
this.comarca = comarca;
}
public String getMarca() {
return marca;
}
public void setMarca(String marca) {
this.marca = marca;
}
public String getImatge() {
return imatge;
}
public void setImatge(String imatge) {
this.imatge = imatge;
}
public String getTematica() {
return tematica;
}
public void setTematica(String tematica) {
this.tematica = tematica;
}
And Location is a composite of type and a realmlist
Location.java
public class Location extends RealmObject implements Serializable {
private String type;
private RealmList<RealmDoubleObject> coordinates;
public Location() {
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public RealmList<RealmDoubleObject> getCoordinates() {
return coordinates;
}
public void setCoordinates(RealmList<RealmDoubleObject> coordinates) {
this.coordinates = coordinates;
}
}
RealmDoubleObject.java
public class RealmDoubleObject extends RealmObject implements Serializable{
private Double value;
public RealmDoubleObject() {
}
public Double getDoublevalue() {
return value;
}
public void setDoublevalue(Double value) {
this.value = value;
}
}
The error is com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at path $[0].location.coordinates[0] but I'm not able to figure out why this number is not "fitting" by RealmDoubleObject.
For those that not familiar with realm RealmList doesn't work and you have to build your own realm object.
Thank you. I hope to find some Realm experts here!
SOLVED:
using Gson deserializer it can be done
First we have to initialize the gson object like this
Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
#Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(RealmObject.class);
}
#Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
})
.registerTypeAdapter(new TypeToken<RealmList<RealmDoubleObject>>() {}.getType(), new TypeAdapter<RealmList<RealmDoubleObject>>() {
#Override
public void write(JsonWriter out, RealmList<RealmDoubleObject> value) throws IOException {
// Ignore
}
#Override
public RealmList<RealmDoubleObject> read(JsonReader in) throws IOException {
RealmList<RealmDoubleObject> list = new RealmList<RealmDoubleObject>();
in.beginArray();
while (in.hasNext()) {
Double valor = in.nextDouble();
list.add(new RealmDoubleObject(valor));
}
in.endArray();
return list;
}
})
.create();
And then we have to put some other constructor method
public RealmDoubleObject(double v) {
this.value = v;
}
and this is all.
Thanks for the help #EpicPandaForce
I'm being given a Json file with the form:
{
"descriptions": {
"desc1": "someString",
"desc2": {"name":"someName", "val": 7.0}
}
}
I have the POJO:
public class CustomClass {
Map<String, Object> descriptions;
public static class NameVal{
String name;
double val;
public NameVal(String name, double val){...}
}
}
I can recreate the json file with the code:
CustomClass a = new CustomClass();
a.descriptions = new HashMap<String, Object>();
a.descriptions.put("desc1", "someString");
a.descriptions.put("desc2", new CustomClass.NameVal("someName", 7.0));
new ObjectMapper().writeValue(new File("testfile"), a);
But, when I read the object back in using:
CustomClass fromFile = new ObjectMapper().readValue(new File("testfile"), CustomClass.class);
then fromFile.descriptions.get("desc2") is of type LinkedHashMap instead of type CustomClass.NameVal.
How can I get Jackson to properly parse the type of the CustomClass.NameVal descriptors (other than making some class that wraps the parsing and explicitly converts the LinkedHashMap after Jackson reads the file)?
Try this. Create a class Description with name and value attributes:
public class Description {
private String name;
private double val;
}
Now in your CustomClass do this:
public class CustomClass {
List<Description> descriptions;
}
And that's it. Remember to create getters and setters because Jackson needs it.
You could try something like this:
public class DescriptionWrapper {
private Description descriptions;
public Description getDescriptions() {
return descriptions;
}
public void setDescriptions(Description descriptions) {
this.descriptions = descriptions;
}
}
public class Description {
private String desc1;
private NameValue desc2;
public String getDesc1() {
return desc1;
}
public void setDesc1(String desc1) {
this.desc1 = desc1;
}
public NameValue getDesc2() {
return desc2;
}
public void setDesc2(NameValue desc2) {
this.desc2 = desc2;
}
}
public class NameValue {
private String name;
private double val;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getVal() {
return val;
}
public void setVal(double val) {
this.val = val;
}
}