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.
Related
Currently I am using the Google's Gson class to parse incoming Ajax JSON strings into Java pojos, as part of the doGet/doPost tasks. I instantiate a new Gson object the usual out from the JSON string the usual way:
JsonObj jsonObj = new Gson().fromJson(jsonStr, jsonObj.class);
The doubt is if I should instantiate a shared gson object in the servlet initialization to avoid doing new Gson() in every servlet doGet/doPost call.
Here Instantiate a new instance of GSON for every serialization? I've learnt that Gson is not a singleton and that some customization is possible with GsonBuilder, but this is not my case.
I am worried about the multithreading behavior of the shared Gson object.
Simple answer: Gson is thread safe and you can share it between servlets. See: Is it OK to use Gson instance as a static field in a model bean (reuse)?
But you should decouple JSON serialization/deserialization logic from your business logic. For example, in Spring is done by *HttpMessageConverter layer. So, first step would be to create shared bean of Gson object and second would be creating abstract layer which allow to exchange implementation if it is needed. If you are writing web-app anyway, Spring is a good choice.
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.
I am working with GSON in my current project, i am amazed to see its power and was wondering how did it work internally. How can a GSON object change the any object into JSON and vice versa. I did read the google user guide but the internal working is not mentioned their. Can anyone explain. Also this question might not appeal some people but i am new to android programming and was exploring things. Although i used gson successfully. But i do like to know its working methodology. Can any one explain.
Thanks a lot.
Gson's internals are built on three core types:
JsonReader reads the elements in a JSON document from a stream.
JsonWriter writes the elements in a JSON document to a stream.
TypeAdapter converts a single JSON element to a single object, or vice versa.
One key pattern is that TypeAdapter is implemented recursively. For example, the TypeAdapter<FoodDelivery> may delegate to a TypeAdapter<Address> and a TypeAdapter<MenuItem>. The TypeAdapterFactory interface makes it easy to build type adapters for arbitrary types.
One other key pattern is that Gson includes some awesome type adapters built-in by default. There's type adapters for primitives, strings, collections. Plus a special type adapter that takes an arbitrary Java class and converts it to a JSON object field-by-field.
I suggest that you do not perform recreation of objects and not force GSON except where it is needed. IMO, you have to use GSON anywhere where you have REST service, but GSON is more slower than java collections (ArrayList or HashMap or any other ...) and you will decrease app performances if you continue to use GSON everywhere.
Second reason is that when you perform object recreation, this is done in phone memory, and just for example, I had a problem with JSON (GSON) object which was exposed over service because it was 35-40MB and object creation uses over 70MB of RAM. There I had OutOfMemoryException, MemoryExhaustedException and more problems this kind.
If this limitations are not interested for you (you don't have large objects, or high speed is not required), then proceed to convert objects to 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.
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...)