How can I easily serialize Java graph to/from JSON? - java

I am struggling to find a library that will serialise a simple graph of Java objects to/from JSON (no need for circular refs or anything). I don't want to have Java class names in the output but including an extra "#type": "foo" property is fine. It must work with untyped collections and maps. I expect to have to do something like mapper.registerType(MyClass.class, "foo") to specify the type mappings but the library must take it from there. Anyone know of such a thing?

Jackson should be able to handle what it is that you are trying to do. Check out the examples from this link, most specifically #4 for polymorphic type deserialization
Jackson
Polymorphic Type Handling
Examples

Take a look at Genson it provides full databinding support, with polymorphic and untyped objects and has many other features.
// this defines aliases for classes, if you don't care of class names being
// serialized then just enabled type ser/deser using builder.setWithClassMetadata(true)
Genson genson = new Genson.Builder()
.addAlias("person", Person.class)
.addAlias("other", Some.class)
.create();
// serialize using with type information
String json = genson.serialize(object);
// deserializing to an unkown type based on the type information in the json string
genson.deserialize(json, Object.class);

Do you search something like this?
http://code.google.com/p/json-io/
json-io consists of two main classes, a reader (JsonReader) and a
writer (JsonWriter). There is a 3rd rigorous test class
(TestJsonReaderWriter). json-io eliminates the need for using
ObjectInputStream / ObjectOutputStream to serialize Java and instead
uses the JSON format.
...
Usage
json-io can be used directly on JSON Strings or with Java's Streams.

Related

jackson-core: Dependent pair, where type family exists before quantifier in Json data

I have some incoming JSON (the field-order of which is not my choice) that embeds a dependent pair:
{
"data": {...},
"evt": "READY",
...
}
and what type I should read data into depends on the value of evt. With just a JsonParser this is impossible because there's no way to store data for later so that it can be returned to once evt is reached.
All of the data I'm parsing (unfortunately) already exists in a ByteBuffer, so is there a better interface to use than JsonParser? I don't want to bring in any more dependencies than jackson-core if it can be helped.
Looks like there is no simple way to achieve this without any additional dependencies.
I suppose, you need to add at least jackson-databind (and also jackson-annotations if not added automatically via Maven/Gradle).
Then you can use an ObjectMapper as an ObjectCodec for the parser and parse the complete JSON either into a TreeNode structure that can be partically parsed later into the correct type or - if you have objects for all types of data - you maybe can directly parse the complete object with matching data type. If needed, a custom ObjectCodec could be implemented to first collect the unknown data and then later process it when the type is known, but implementing an ObjectCode does not seem to be that easy.
Instead of Jackson you could use GSON which can either parse the data into the complete object structure or a generic JSON object tree without any additional dependencies.
If you really cannot add additional dependencies, then you could implement a SAX-XML-Parser-like logic using JsonParser.nextToken, but I suppose that would require a lot of custom logic.

Jackson databind - how to deserialize an object without specifying the target class?

I am migrating from snakeyaml and a feature snakeyaml had is that it automatically wrote the object type in the output YAML so that deserialization would be transparent and easy. I cannot seem to find the same feature in Jackson Databind.
If I merely specify Object.class, I get a LinkedHashMap which is to be expected. Additionally, for this to work, I would have to see the class type in the JSON and I haven't found a native way to do that.
Is this required?
If I understand the problem correctly perhaps you are looking for JsonTypeInfo
From the docs
// Include Java class name ("com.myempl.ImplClass") as JSON property "class"
#JsonTypeInfo(use=Id.CLASS, include=As.PROPERTY, property="class")
I ended up prepending the class name before the actual object data and then split that out prior to actually deserializing the data back into an object which is what snakeyaml does automatically. I was hoping to do this automatically in Jackson though.

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.

Java serialization to string

I have the following declaration of the static type Object:
Integer typeId;
//Obtaining typeId
Object containerObject = ContainerObjectFactory.create(typeId);
The factory can produce different types of container objects, e.g. Date, Integer, BigDecimal and so forth.
Now, after creating the containerObejct I need to serialize it to an object of type String and store it into a database with hibernate. I'm not going to provide Object-relational mapping because it doesn't relate to the question directly.
Well, what I want to do is to serialize the containerObject depending on it runtime-type and desirialize it later with the type it was serialized. Is it ever possible? Could I use xml-serialization for those sakes?
There are numerous alternatives, and your question is quite broad. You could:
use the native Java serialisation, which is binary, and then Base64 encode it
use an XML serialisation library, such as XStream
use a JSON serialisation library, such as Gson
One key feature you mention is that the object type needs to be embedded in the serialised data. Native Java serialisation embeds the type in the data so this is a good candidate. This is a double-edged sword however, as this makes the data brittle - if at some time in the future you changed the fully qualified class name then you'd no longer be able to deserialise the object.
Gson, on the other hand, doesn't embed the type information, and so you'd have to store both the JSON and the object type in order to deserialise the object.
XML and JSON have advantages that they're a textual format, so even without deserialising it, you can use your human eyes to see what it is. Base64 encoded Java serialisation however, is an unintelligible blob of characters.
There are multiple ways, but you need custom serialization scheme, e.g.:
D|25.01.2015
I|12345
BD|123456.123452436
where the first part of the String represents the type and the second part represents the data. You can even use some binary serialization scheme for this.

Internal working of GSON

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.

Categories