My situation is as follows: Object TableC
has 4 fields. Only 3 fields (field_C1
, field_C2
, and field_C3
) are read from the JSON string. The fourth field field_C4
is defined within the object with a default value.
When I serialize the object instance (for output) - it ignores the field field_C4
, I was expecting the default value of "1"
or "null"
. When I explicitly define a value to the instance-field within the program to "NEW"
, it does include it in the Json output string.
Looking at the output, it looks as if the constructor is also ignored when the object instance is created during deserialization.
What would be the best practice to activate the other fields for the object instance - which are not included in the Deserialized version of the input Json String?
package newpackage;
import java.util.List;
import com.google.gson.*;
public class jsonwithconstructor {
public static void main(String[] args) throws ClassNotFoundException {
String jsonstring = "{'TableC':["
+ "{'field_C1':'C_11','field_C2':'C_12','field_C3':'C_13'},"
+ "{'field_C1':'C_21','field_C2':'C_22','field_C3':'C_23'}"
+ "]}";
jsonstring = jsonstring.replace('\'', '"');
System.out.println(jsonstring);
RootObject root = new GsonBuilder().create().fromJson(jsonstring, RootObject.class);
for (int i=0; i < root.TableC.size(); i++){
System.out.println(root.TableC.get(i));
}
System.out.println();
//root.TableC.get(0).field_C4 = "NEW";
for (int i=0; i < root.TableC.size(); i++){
System.out.println(root.TableC.get(i));
}
System.out.println();
Gson gson = new Gson();
String jsonoutput = gson.toJson(root);
System.out.println(jsonoutput);
}
public class TableC{
public String field_C1;
public String field_C2;
public String field_C3;
public String field_C4 = "1";
public TableC(){
this.field_C4 = "1";
}
@Override
public String toString() {
return ("TableC" + ", " + this.field_C1 + ", " + this.field_C2 + ", " + this.field_C3 + ", " + this.field_C4);
}
}
public class RootObject{
public List<TableC> TableC;
}
}
The output is shown below:
{"TableC":[{"field_C1":"C_11","field_C2":"C_12","field_C3":"C_13"},{"field_C1":"C_21","field_C2":"C_22","field_C3":"C_23"}]}
TableC, C_11, C_12, C_13, null
TableC, C_21, C_22, C_23, null
TableC, C_11, C_12, C_13, NEW
TableC, C_21, C_22, C_23, null
{"TableC":[{"field_C1":"C_11","field_C2":"C_12","field_C3":"C_13","field_C4":"NEW"},{"field_C1":"C_21","field_C2":"C_22","field_C3":"C_23"}]}
Gson constructs the values of fields in deserialized objects with reflection, so it will set the values based on what's in the JSON only. Until Google provides a fix for this issue, there isn't that much you can do.
There are a number of workaround objects you have in the meantime:
null
, but they do need to be mutable.final
. This a good way to do it if they are immutable.ExclusionStrategy
, and mark the particular fields that should be ignored using FieldAttributes
I agree that all of these have drawbacks, but as I said above, this is an open issue with Gson.
Using Gson v2.7, I can see that it calls the default constructor of the deserialized object and any value initialized inside that is retained. However, I was using "new Gson()" instead of "GsonBuilder", if that makes any difference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With