Why does GSON use fields and not getters/setters? - java

Why does GSON use ONLY fields(private,public,protected)?
Is there a way to tell GSON to use only getters and setters?

Generally speaking when you serialize/deserialize an object, you are doing so to end up with an exact copy of the state of the object; As such, you generally want to circumvent the encapsulation normally desired in an OO design. If you do not circumvent the encapsulation, it may not be possible to end up with an object that has the exact same state after deserialization as it had prior to serialization. Additionally, consider the case where you do not want to provide a setter for a particular property. How should serialization/deserialization act if you are working through the getters and setters?

Is there a way to tell GSON to use only getters and setters?
Not yet.
From the design doc:
[T]here are good arguments to support properties as well. We intend to enhance Gson in a latter version to support properties as an alternate mapping for indicating Json fields. For now, Gson is fields-based.

It is possible to to patch Gson to use getters.

The vague outline of how this works in our app is that we have a lot of TypeAdapter implementations - some for specific value-like objects and some for bean-style objects where we know that JavaBeans logic will work. We then jam all of these onto a GsonBuilder before creating the Gson object.
Unfortunately, GSON is really crap at handling types like Object[]. We mostly saw this when we were trying to make a JSON object to represent method parameters. The workaround for that was to make custom TypeAdapter instances which reflect the methods. (This does mean that you end up using one Gson instance per method you intend to call...)

Related

Why isn't Google's Gson static?

Out of curiosity, why do I have to instantiate Gson? I can't see any reason as to why Gson#toJson and Gson#fromJson can't be static. Doing new Gson().toJson(...) every time seems silly when I could simply use Gson.toJson(...). Is there some instance specific data being generated I am not aware of?
This is because a Gson object may be made by using GsonBuilder which allows Gson to have configuration options other than the default ones.

Instantiate a new instance of GSON for every serialization?

Currently, I have a lot of occurences in my code that read as follows: result = new Gson().fromJson(someString, ResultContainer.class); Should I share the GSON object over all those places? If so, per object or static per class (potentially even superclass?)
I am asking mainly because if sharing the reference statically is fine, then why isn't the Gson object static in the first place? Unless one uses fancy custom serialization rules, the method above pretty much covers what one would want Gson to do.
According to the GSON user guide:
The Gson instance does not maintain any state while invoking Json operations. So, you are free to reuse the same object for multiple Json serialization and deserialization operations.
It's not singleton because you can configure it differently via GsonBuilder.
Sharing the Gson is fine.
You can configure a Gson using GsonBuilder therefore Gsonis not a singleton.

How is javax.ws.rs.client.Entity serializing objects to json?

What serializer is Entity.json(T entity) using to serialize/deserialize objects? Is it somehow possible to use a custom serializer?
In my case the serialization is wrong because my object contains fields with the Guava Optional data type and absent values are returned as {"present":false} instead of null.
The JSON serializer isn't specified by JAX-RS, it depends on your configuration. For example, Jersey JAX-RS allows several (https://jersey.java.net/documentation/latest/media.html), including
MOXy
Java API for JSON Processing (JSON-P)
Jackson
Jettison
But a better solution is not to use Optional (either Guava or Java 8) for fields. See http://blog.joda.org/2014/11/optional-in-java-se-8.html
My only fear is that Optional will be overused. Please focus on using
it as a return type (from methods that perform some useful piece of
functionality) Please don't use it as the field of a Java-Bean.
Not directly solving your problem. I suggest you use Googles Gson as a parser. It is very flexible and configurable.
Tutorial
It also skips blank fields so the json size is not too large.

Extra/dupe members in SOAP response prevents serialization (Axis, Java, Gson)

I am using Axis to call a SOAP-based web service. I'm then trying to serialize the returned remote object as JSON, using the Google Gson library.
The serialization to JSON fails, with Gson complaining that "there are multiple elements with the name __equalsCalc()).
When I inspect the returned object in my IDE (Eclipse), I can see that this is true -- the returned object has three members called __equalsCalc() and another three called __hashCode.
I know from looking around that these are added by WSDL2Java (I think) in order to avoid recursion. My question is, why are there THREE of each? And how can I get the serializer to ignore these? They're not actually part of the object's definition (it's called a RemoteProject, for reference). Can I do something hackish like cast the RemoteProject to a RemoteProject to get it to drop those members?
This turns out to be not too hard to solve. I have multiple copies of the same instance var because the class being serialized is shadowing fields of the same name from superclasses. Since I don't care about these fields, the best approach in Gson is to write a custom ExckusionStrategy which can selectively ignore fields based on their name:
http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/ExclusionStrategy.html
I don't know GSon.
With Jackson, you can annotate properties (i.e - fields that have getters/setters according to Java bean convention) with #JsonIgnore.
This way you can prevent issues like recursion/no matching setter or getter and so on...
Try to find out if you have the same at GSon or use Jackson.

JAXB is good until I need to do something complex. What are the alternatives?

JAXB works well until I need to do something like serialize beans for which I cannot modify the source. If the bean doesn't have a default constructor or if it refers to objects I want to mark transient then I'm stuck writing a separate bean which I can annotate and then manually copy the information over from the other bean.
For instance, I wanted to serialize exception objects, but found that the only way to do that was use a hack that required using com.sun.* classes.
So, what alternatives are there? What's the next most popular xml serializing api? It would be nice to be able to do things like:
Choose at serialization time whether to include certain fields in the result. (marking things transient when running the serializer).
Handle loops in the object graph by using references or something other than just dying.
Perhaps annotate an object so that in version 1 it serializes things in one way and in version 2 it serializes them in another. Then when serializing I just choose which version of the object ot serialize.
Have a way to generate XSDs from annotations on an object.
Basically I just want more flexibility than I currently have with JAXB.
Well the standard answer for wanting a uber configurable serialisation framework is xstream.
JAXB is a spec, so you can pick from different implementations. EclipseLink JAXB (MOXy) has extensions for what you are asking:
Externalized Metadata
Useful when dealing with classes for which you cannot annotate the source or to apply multiple mappings to an object model.
http://bdoughan.blogspot.com/2010/12/extending-jaxb-representing-annotations.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/EclipseLink-OXM.XML
XPath Based Mapping
For true meet-in-the-middle OXM mapping:
http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html
http://bdoughan.blogspot.com/2011/03/map-to-element-based-on-attribute-value.html
http://bdoughan.blogspot.com/2010/07/xpath-based-mapping.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted/MOXyExtensions
JPA Compatibility
Including support for bi-directional relationships.
http://bdoughan.blogspot.com/2010/07/jpa-entities-to-xml-bidirectional.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA
Also look at JIBX. It's a good xml<->object mapper. My experience is though that if your objects have a somewhat funky relationships it's often easier to create a wrapper object that hides that complexity and then map that object with JIBX.
XStream is a popular XML serialisation library that claims to be able to serialize just about anyting, regardless of constructors or other problems (even deserialize final fields). Give it a try.
Requires no modifications to objects. Serializes internal fields, including private and final. Supports non-public and inner classes. Classes are not required to have default constructor.

Categories