Open GoogleCodeExporter opened 9 years ago
This will be extremely useful for synthetic fields and for type hierarchies.
I.e. say you have a base class with an Id field that you want to serialize with
a type specific name. You could have the Id be transient and have a getId
method that child classes could override to return their Id types etc.
Original comment by nfiedel
on 17 Sep 2010 at 5:58
Original comment by limpbizkit
on 6 Oct 2010 at 5:38
Issue 185 has been merged into this issue.
Original comment by limpbizkit
on 6 Oct 2010 at 6:09
Original comment by limpbizkit
on 6 Oct 2010 at 6:10
Original comment by inder123
on 3 Nov 2010 at 12:25
It would be nice if GSON used getters and setters, actually it is a bit
confusing to use as one cannot transform data in setters.
Original comment by astronau...@gmail.com
on 25 May 2011 at 9:36
[deleted comment]
[deleted comment]
[deleted comment]
Hi! Actually it is not very hard to check out sources of GSON and add "use
getters" ability. I required this in order to be able to work with Hibernate
proxies seamlessly ... if anybody is interested, mail me to
jakub.gemrot@gmail.com (I'm sorry I don't have time to create patches right
now...).
The key place to patch is JsonSerializationVisitor.visitFieldUsingCustomHandler(
FieldAttributes f, Type declaredTypeOfField, Object parent)
Look for:
obj = f.get(parent);
Than just replace with:
Object obj = null;
if (useGetters) {
String fieldName = f.getName();
if (fieldName == null || fieldName.length() == 0) throw new RuntimeException("fieldName is invalid!");
String getter = null;
if (declaredTypeOfField == boolean.class) {
getter = "is";
} else
if (declaredTypeOfField == Boolean.class) {
getter = "get"; // should be get... but some frameworks will put "is" ... checked later if this is not found...
} else {
getter = "get";
}
getter += fieldName.substring(0, 1).toUpperCase() + (fieldName.length() <= 1 ? "" : fieldName.substring(1));
Method method = null;
try {
method = parent.getClass().getMethod(getter);
} catch (Exception e) {
// no getter present
if (declaredTypeOfField == Boolean.class) {
// getter might start with "get" not "is"
getter = "is" + fieldName.substring(0, 1).toUpperCase() + (fieldName.length() <= 1 ? "" : fieldName.substring(1));
try {
method = parent.getClass().getMethod(getter);
} catch (Exception e2) {
// no, event "is" prefixed getter for Boolean.class does not exist
}
}
}
if (method == null) {
obj = f.get(parent);
} else {
try {
obj = method.invoke(parent);
} catch (Exception e) {
throw new RuntimeException("Could not invoke getter: " + obj.getClass() + "." + getter + "() !", e);
}
}
} else {
obj = f.get(parent);
}
See how boolean.class & Boolean.class are handled, I know it looks wierd. The
trick is that you have to take care of boolean.class as well as Boolean.class.
Eclipse is suggesting that "Boolean" bean properties should use getters
prefixed with "get" but Hibernate is using "is". So that case must be treated
extra.
Cheers!
Jimmy
Original comment by Jakub.Ge...@gmail.com
on 18 Jun 2011 at 3:38
Oh, and watch out for failing tests inside DefaultTypeAdaptersTest working with
Date/Timestamp/etc... just comment them out :)
Best, Jimmy
Original comment by Jakub.Ge...@gmail.com
on 18 Jun 2011 at 3:38
If you wish to test your code after that, you may use this (it's not actually a
test case ... but it will print serialized Gson that will contain different
values than actually stored due to the getter definition):
public static class MyUtilClass {
private int util = 5;
public MyUtilClass() {
}
public MyUtilClass(int util) {
this.util = util;
}
public int getUtil() {
return util * 10;
}
public void setUtil(int util) {
this.util = util * 10;
}
}
public static class MyClass {
private int value = 10;
private MyUtilClass cls = new MyUtilClass();
private MyUtilClass[] clss = new MyUtilClass[3];
private List<MyUtilClass> list = new ArrayList<MyUtilClass>(10);
private Map<Integer, MyUtilClass> map = new HashMap<Integer, MyUtilClass>();
private Set<MyUtilClass> set = new HashSet<MyUtilClass>();
private Boolean b1 = true;
private boolean b2 = true;
public MyClass() {
clss[0] = new MyUtilClass(1);
clss[2] = new MyUtilClass(2);
list.add(new MyUtilClass(3));
list.add(new MyUtilClass(4));
map.put(1, new MyUtilClass(5));
map.put(2, new MyUtilClass(6));
set.add(new MyUtilClass(7));
set.add(new MyUtilClass(8));
}
public int getValue() {
return value * 10;
}
public void setValue(int value) {
this.value = value * 100;
}
public Boolean isB1() {
return false;
}
public boolean isB2() {
return false;
}
}
public void testClassSerialization() {
GsonBuilder builder = new GsonBuilder();
builder.setUseGetters(true);
builder.setPrettyPrinting();
gson = builder.create();
MyClass obj = new MyClass();
String json = gson.toJson(obj);
System.out.println(json);
}
Best,
Jimmy
Original comment by Jakub.Ge...@gmail.com
on 18 Jun 2011 at 3:42
In Gson 2.1, it's possible to do this as an extension with a TypeAdapterFactory
based on ReflectiveTypeAdapterFactory. We may want to provide an extension.
Original comment by limpbizkit
on 29 Dec 2011 at 5:36
Issue 285 has been merged into this issue.
Original comment by limpbizkit
on 29 Dec 2011 at 5:52
I think this implementation is good, except I suggest make configurable to
throw an exception or not. If getter is not found, it maybe treated as this
field is not exposed. This is the common case, why getter/setter not provided
for a field.
Second thing: I should swap the two process way of Boolean class, i think "is"
prefix is more common than "get" for these fields.
Original comment by h...@hron.me
on 11 Mar 2012 at 3:54
[deleted comment]
I made a small code to support bind by getter/setter method or field.
Here is the sample code:
GsonBuilder bsonBuilder = new GsonBuilder();
Gson gson = bsonBuilder.setFieldBindingStrategy(FieldBindingStrategy.GET_METHOD).create();
// or by field modifier: gson = bsonBuilder.setFieldBindingStrategy(FieldBindingStrategy.FieldModifier.valueOf(Modifier.PRIVATE+Modifier.PROTECTED)).create();
Original comment by 70l...@gmail.com
on 21 Feb 2014 at 7:27
Attachments:
[deleted comment]
one more suggestion: comparing to fastJson or jackson, the performance is a bit
slower. I think performance of gson should be improved continually.
Original comment by 70l...@gmail.com
on 21 Feb 2014 at 7:30
Original issue reported on code.google.com by
Germanattanasio
on 7 Sep 2010 at 2:04