GSON does not cast Json string to class - android

I am trying to convert JSonObject string to some specific classes.
MyClass mc= new Gson().fromJson(jo.toString(),MyClass.class);
After this step all values of mc is null.
Value of the jo.toString() :
{
"__type":"MyClass:#MyProject.Model",
"ID":1,
"Comment":"First Record",
"SubClassID":534,
"Active":true,
"Date":"\/Date(1323087840000+0200)\/"
}
MyClass.java has attributes ID, Comment...
Thanks Regards...
MyClass.Java:
public class MyClass extends ABase
{
private String _Comment;
public String getComment(){
return _Comment;
}
public void setComment(String value){
_Comment = value;
}
private Integer _ID;
public Integer getID(){
return _ID;
}
public void setID(Integer value){
_ID = value;
}
private java.util.Date _Date;
public java.util.Date getDate(){
return _Date;
}
public void setDate(java.util.Date value){
_Date = value;
}
}

The problem is that the JSON element names do not match the Java field names, and no explicit alternative name-mapping configuration was provided to Gson.
Possible Solutions:
Change the Java field names to exactly match the JSON element names. This of course isn't always possible, e.g., when the JSON element names include characters or formats not valid for Java field names.
Change the JSON element names to exactly match the Java field names. This of course isn't always possible, e.g., when the JSON is from a third party.
Provide Gson with name-mappings, using either the #SerializedName annotation, or a FieldNamingPolicy.

Related

is it possible to set default value using annotations in gson?

is it possible using annotation set default value to Gson properties?
i want to use this default values after deSerialize/serialize
#SerializedName(key = "a", defaultValue = "hi")
public String a;
#SerializedName("b")
public String b;
You can set a default value in your setter method if the variable is null
#SerializedName("yourVariable")
public String yourVariable;
public String getYourVariable(){
if(yourVariable==null){
return defaultValue;
}
return yourVariable;
}

Android Firebase, Unable to fetch the data

I created a family tree application on java and mysql database. Now I am testing an android app for the same. So I converted my mysql database file to JSON format and uploaded it to firebase. When I am inserting records on it, it is working perfectly fine but when I try to fetch the data it is showing the error:
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to int
at com.google.android.gms.internal.firebase_database.zzkt.zzb(Unknown Source:180)
What should be the problem? I tried deleting the data from the database which I uploaded through JSON file and then inserted records directly from app into database and fetch them, it worked fine but when I am adding record from JSON file only then It is creating problem.
here is the code from the app for fetching data:
public void clicked(){
mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<Family> FamilyList = new ArrayList<>();
for (DataSnapshot adSnapshot: dataSnapshot.getChildren()) {
Family f = adSnapshot.getValue(Family.class);
FamilyList.add(f);
// adsList.add(adSnapshot.getValue(Family.class));
}
Toast.makeText(MainActivity.this, "Total Records: "+FamilyList.size(), Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Family Model Class:
public class Family {
int id;
String name;
String fatherName;
int fid;
String city;
String state;
public Family(int id, String name, String fatherName, int fid, String city, String state) {
this.id = id;
this.name = name;
this.fatherName = fatherName;
this.fid = fid;
this.city = city;
this.state = state;
}
public Family()
{
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFatherName() {
return fatherName;
}
public void setFatherName(String fatherName) {
this.fatherName = fatherName;
}
public int getFid() {
return fid;
}
public void setFid(int fid) {
this.fid = fid;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
Here is the JSON Record Sample
It is the records which I entered through App
I think the converted JSON treated id and fid as String, while in mySQL they are int. (am I correct?)
Tell me if any other code is needed.
The problem relies on here
Family f = adSnapshot.getValue(Family.class);
you are trying to get data in an inappropriate type.
You should correct this by checking Family.class and check if the values there are the same as they are in your database structure in firebase, it will be helpful if you put your database structure here, or some images.
Check if for example in Family.class you have in your variable types the same as they are in firebase, with the same name also.
So for example if in firebase there is an string called name you should have in your constructor inside Family.class the same type and name.
String name;
and in Firebase your json key should be name too.
For instance, check this
your Family class for example should have the variables with the same name and type as your database.
Also check, if the value in firebase has "" is an String type and in your POJO you should have a variable with the type String for what you are trying to access, but if the value dosnt have "" it should be a long , int, double or any type of number.
EDIT: check this structure
It has all the values types as String, but in your Family.class you have the values right for this type of structure.
you should change your database at firebase so all your types matches with the ones in your Family.class, either way it won't fetch your values
Note: if you want to fetch all your values like they are at the first image, just change in Family.class from this:
int id;
String name;
String fatherName;
int fid;
String city;
String state;
to this:
String id;
String name;
String fatherName;
String fid;
String city;
String state;
Also change your constructor types and everything to match all Strings
The thing is that firebase creates unique IDs for each element in your database structure, and the types imported from your MySQL database are not the same as the firebase ones, I suggest you to either change your Family.class variable types as I mentioned above, or replicate your MySQL database with firebase and the same variable types.
This is happening because you have a variable of integer datatype in your model but you are returning String from Firebase... either convert your variable to string or return integer from firebase....
Both model and Firebase variable should be of a same data type.
As per your below error:-
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to int at com.google.android.gms.internal.firebase_database.zzkt.zzb(Unknown Source:180)
I think, you need to check somewhere you tried to store value in int which is store in firebase in string.
So first check it and if necessary to cast then casting your value using Integer.parseInt or Integer.valueof
for example,
Integer.valueOf(dataSnapShot.getValue());
or
Integer.parseInt(dataSnapShot.getValue());
For more understanding this you can also refer stack overflow's below links:
Firebase DatabaseException: Failed to convert value of type java.lang.Long to String
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to double
Firebase android error "Failed to convert value of type "

From JSon array to custom data structure

Say I need to fill a Binary Search Tree with data obtained from Server. Say further that the data coming from server is a json array of nodes
"parts":[{"id":1,"name":"apple"},{"id":12,"name":"orange"},{"id":21,"name":"pen"},{"id":214,"name":"kite"}]//where each {} represents a node
How do I use GSon to read the array of Nodes into my BST?
If you recall a BST has two classes
public class BST{
private Note root;
}
public class Node{
String el;
Node left, right;
}
If BST is too hard, image something simpler
public class MyDataStructure{
private List<Part> partsList;
…
}
public class Part{
String el;
List<String> stuff;
}
How do I populate MyDataStructure with partsList using GSon on android? As a side note, I would rather help solving the MyDataStruction version of the problem.
ok.. you can use this as reference:
define a class pojo
and a Fruit(is the array/list/collection)
the pojo
class Pojo {
#Override
public String toString() {
return "Pojo [parts=" + parts + "]";
}
private List<Fruits> parts;
}
the fruit
class Fruits {
private int id;
private String name;
#Override
public String toString() {
return "[id=" + id + ", name=" + name + "]";
}
}
the implementation
String json = "{\"parts\": [{\"id\":1,\"name\":\"apple\"},{\"id\":2,\"name\":\"pear\"},{\"id\":3,\"name\":\"kiwi\"}]}";
Gson g = new Gson();
Pojo p = g.fromJson(json, Pojo.class);
System.out.println(p);
the MyDataStructure population
add to the pojo a setter getter so you can work with the list, add too setter and getter for the fruit class so you can get the id and the name..
so in the pojo object p you can do p.getList() and iterate over the elements
Something like:
Pojo p = g.fromJson(json, Pojo.class);
System.out.println(p);
for (Fruits f : p.getParts()) {
System.out.println(f.getId());
System.out.println(f.getName());
}

How to get timestamp(rowversion) from sql azure to android with mobileservice

i have a problem getting timestamp(rowversion) from my SQL Azure database.
In my tables there is a column with datatype timestamp. This timestamp isn't similar to datetime, it's more like a rowversion.
I can get all other data in this table with the query from MobileServiceTable, there is no problem.
But this special datatype is a problem.
My class for this table looks like:
public class ArbeitsgangBezeichnung {
#com.google.gson.annotations.SerializedName("id")
private int ID;
#com.google.gson.annotations.SerializedName("ABZ_ArbeitsgangBezeichnungID")
private int ABZ_ArbeitsgangBezeichnungID;
#com.google.gson.annotations.SerializedName("ABZ_Bezeichnung")
private String ABZ_Bezeichnung;
#com.google.gson.annotations.SerializedName("ABZ_RowVersion")
private StringMap<Number> ABZ_RowVersion;
//constructor, getter, setter, etc....
}
If i login in Azure and look at the table, there are my example values and the automatic generated timestamp. The timestamp value looks like "AAAAAAAAB/M=". If i login in sql database and let me show the data, then for timestamp there is only "binarydata" (in pointed brackets) and not that value as it is shown in Azure.
The variable "ABZ_RowVersion" should include this timestamp, but the data in the StringMap doesn't look like the one in Azure. I tried String and Byte as datatype for the StringMap, but it doesn't helped.
I tried byte[] for ABZ_RowVersion, but then i got an exception in the callback method.
Then i tried Object for ABZ_RowVersion, that time i found out, that it is a StringMap, but nothing more.
Does anybody know, how to get the data from timestamp, i need it for comparison.
Thanks already
When you create a timestamp column in a table, it's essentially a varbinary(8) column. In the node SQL driver, it's mapped to a Buffer type (the usual node.js type used for binary data). The object which you see ({"0":0, "1":0, ..., "length":8}) is the way that a buffer is stringified into JSON. That representation doesn't map to the default byte array representation from the Gson serializer in Android (or to the byte[] in the managed code).
To be able to use timestamp columns, the first thing you need to do is to "teach" the serializer how to understand the format of the column returned by the server. You can do that with a JsonDeserializer<byte[]> class:
public class ByteArrayFromNodeBufferGsonSerializer
implements JsonDeserializer<byte[]> {
#Override
public byte[] deserialize(JsonElement element, Type type,
JsonDeserializationContext context) throws JsonParseException {
if (element == null || element.isJsonNull()) {
return null;
} else {
JsonObject jo = element.getAsJsonObject();
int len = jo.get("length").getAsInt();
byte[] result = new byte[len];
for (int i = 0; i < len; i++) {
String key = Integer.toString(i);
result[i] = jo.get(key).getAsByte();
}
return result;
}
}
}
Now you should be able to read data. There's still another problem, though. On insert and update operations, the value of the column is sent by the client, and SQL doesn't let you set them in them. So let's take this class:
public class Test {
#SerializedName("id")
private int mId;
#SerializedName("name")
private String mName;
#SerializedName("version")
private byte[] mVersion;
public int getId() { return mId; }
public void setId(int id) { this.mId = id; }
public String getName() { return mName; }
public void setName(String name) { this.mName = name; }
public byte[] getVersion() { return mVersion; }
public void setVersion(byte[] version) { this.mVersion = version; }
}
On the insert and update operations, the first thing we need to do in the server-side script is to remove that property from the object. And there's another issue: after the insert is done, the runtime doesn't return the rowversion property (i.e., it doesn't update the item variable. So we need to perform a lookup against the DB to retrieve that column as well:
function insert(item, user, request) {
delete item.version;
request.execute({
success: function() {
tables.current.lookup(item.id, {
success: function(inserted) {
request.respond(201, inserted);
}
});
}
});
}
And the same on update:
function update(item, user, request) {
delete item.version;
request.execute({
success: function() {
tables.current.lookup(item.id, {
success: function(updated) {
request.respond(200, updated);
}
});
}
});
}
Now, this definitely is a lot of work - the support for this type of column should be better. I've created a feature request in the UserVoice page at http://mobileservices.uservoice.com/forums/182281-feature-requests/suggestions/4670504-better-support-for-timestamp-columns, so feel free to vote it up to help the team prioritize it.

How to get single string value from Json object Android?

I have this Json statement :
{name=Adam Schmidt, id=43}
and I want to extract the value of the name,
trying this code but it didn't work
// parse json data
try {
JSONObject userObject = new JSONObject(result);
userName = userObject.getString("name");
tvName.setText(userName);
} catch (Exception ex) {
ex.printStackTrace();
}
You statement is not valid json. Here's the sample of valid json.
{\"name\":\"Adam Schmidt\", \"id\":43}
Update:
For number value, no quotation mark
Use GSON. Super easy.
Declare a class that represents your JSON structure:
public class Person {
private String name;
private int id;
public String getName() {
return name;
}
public int getId() {
return id;
}
}
Then you can do:
String json = "{\"name\":\"Adam Schmidt\", \"id\":43}";
String userName = new Gson().fromJson(json, Person.class).getName();
tvName.setText(userName);
This is much better than haphazardly parsing chunks with various get methods all over your code. Plus you get a nice object to pass around and use in your object oriented code.

Categories

Resources