Reputation: 1042
I've managed to convert POGO to json via
class Test {
String test
}
def local = new Test()
local.test = "1234"
render test as JSON
However when trying to convert a java class (declared in a different library) I'm always getting back the class type
public class RegistrationDetails {
/**
* The registration token used to identify the device from now on.
*/
public String registrationToken;
}
RegistrationDetails details = new RegistrationDetails()
details.registrationToken="123"
render details as JSON
instead of getting
{
"registrationToken":"123"
}
Instead I'm getting back
{
"class": "data.com.shared.RegistrationDetails"
}
Am I missing something ?
Upvotes: 1
Views: 732
Reputation: 75671
Converting an object to JSON is based on properties. String test
in a Groovy class defines a property named "test" because it's a field with no scope modifier. It defaults to public, and the Groovy compiler converts String test
to a private field and a getter and a setter. If you decompile Test
(e.g. with jd-gui or another decompiler) you'll see something similar to this (with a bunch of other code that's not relevant here):
public class Test implements GroovyObject {
private String test;
...
public String getTest() {
return test;
}
public void setTest(String paramString) {
test = paramString;
}
}
It won't replace an existing getter or setter, so you're free to customize either or both if you need custom logic when getting and/or setting. If you explicitly make the field public (public String test
) or use any other scope modifier then this conversion doesn't occur.
This is how domain classes work; Hibernate doesn't have any support for Groovy but it doesn't need any - it sees the getters and setters like it would if you had created a typical verbose POJO. It's also how Spring bean dependency injection works; if you have a field in a controller/service/taglib/etc. like def sessionFactory
or SessionFactory sessionFactory
, Groovy adds a getter and setter, and Spring sees the setter and since Grails uses autowiring by name, if there's a bean named "sessionFactory" Spring will call your setter and inject it.
Your Java class doesn't have a property - it has a public field, and the Java compiler doesn't do anything special with it, and neither Groovy nor Grails do anything with it either since it's a Java class. So the only data that's available from the class via a getter is the class since every class has a getClass
method.
The JSON conversion excludes the class
"property" in Groovy classes but not Java but that appears to be a bug; the loop in GenericJavaBeanMarshaller (the helper class for POJOs) only excludes PropertyDescriptor
s that have no getter, but the loop in GroovyBeanMarshaller excludes the getMetaClass
and getClass
getters.
Upvotes: 3