Extending default Jackson deserialization - jackson

How can one obtain a default deserialized object in a custom Jackson deserializer?
I have an object which contains some fields which are not to be serialized, but which I wish to always be populated upon deserialization. In other words, a post-deserialize step.
I have created my own deserializer and annotated the class with a corresponding #JsonDeserialize, but I don't want to deserialize each field in the domain object by hand. Is there a way to get the regular deserialized object so I can just populate my custom fields? (Or else, just register a post-deserialization processor on a bean)
I have seen the answer to this question which hints at an answer, but I'm sufficiently unaware of the Jackson API to determine how best to actually effect this.

This can be achieved by using a BeanSerializerModifier and extending BeanSerializerBase, as per #ryanp's answer to this question.

Related

Jackon JSON: Polymorphic deseralization when subclasses are unknown

I'm trying to do some polymorphic deseralization of JSON using Jackson, however the list of subclasses is unknown at compile time, so I can't use a #JsonSubtype annotation on the base class.
Instead I want to use a TypeIdResolver class to perform the conversion to and from a property value.
The list of possible subclasses I might encounter will be dynamic, but they are all registered at run time with a registry. So I would appear to need my TypeIdResolver object to have a reference to that registry class. It has to operate in what is essentially a dependency injection environment (i.e I can't have a singleton class that the TypeIdResolver consults), so I think I need to inject the registry class into the TypeIdResolver. The kind of code I think I want write is:
ObjectMapper mapper = new ObjectMapper();
mapper.something(new MyTypeIdResolver(subclassRegistry));
mapper.readValue(...)
However, I can't find a way of doing the bit in the middle. The only methods I can find use java annotations to specify what the TypeIdResolver is going to be.
This question Is there a way to specify #JsonTypeIdResolver on mapper config instead of annotation? is the same, though the motivation is different, and the answer is to use an annotation mixin, which won't work here.
SimpleModule has method registerSubtypes(), with which you can register subtypes. If only passing Classes, simple class name is used as type id, but you can also pass NamedType to define type id to use for sub-class.
So, if you do know full set, just build SimpleModule, register that to mapper.
Otherwise if this does not work you may need to resort to just sharing data via static singleton instance (if applicable), or even ThreadLocal.
Note that in the end what I did was abandon Jackson and write my own much simpler framework based on javax.json that just did the kinds of serialisation I wanted in a much more straightforward fashion. I was only dealing with simple DTO (data transfer object) classes, so it was just much simpler to write my own simple framework.

Can I use a DataSet as my Entity?

Can someone point me to a good explanation of the criteria a class must meet to use the default deserializaton for Jackson?
I can do a post and supply a HashMap collection of string/jsonObjects, but it won't work with a dataset that contains the same information in a row. I tried implementing my own Deserializer but the response is always "Unprocessable Entity". I have been successful using specific classes, but I am trying to generalize my solution by passing a dataset.
Obviously I need a better understanding of what is happening! TIA!
It depends on rough type of your class. Jackson has specialized handling for:
Arrays of types
Collection implementations
Map implementations
Enums
Other
If type is none of first 4 categories, it will be considered "Other", and expected to follow Java Bean convention of either public fields, or getters and/or setters.
There also has to be a no-argument constructor (need not be public), or another constructor annotated with #JsonCreator -- expect that some public single-argument constructors (String, int/Integer, long/Long, boolean/Boolean) are also accepted when binding from JSON Scalar values.
But to get more information you really should share the actual exception you get: above is just the general idea of what is needed. Jackson can work with all kinds of classes, and is not particularly strict in how classes are defined. But it does have expectations on how various JSON Structures match with POJOs.

flexjson and versioning : how accommodating change is flexjson?

I'm considering using flexjson to serialise my business objects to a file in an android application, simply using JSONSerializer().deepSerialise(myObject) and JSONDeserializer().deserialise(jsonString) with all the default transformers and object factories.
I'm hoping that once the application is released any changes to the business model should be accommodated by writing flexjsons transformers and object factories in the new release to maintain compatibility with previous versions.
What I'm not sure about is what changes the default transformers and object factories can cope with.
i.e if I add a field to a class and deserialise from an old version without the field into the new class will it fail or will the new field be null or 0 (if a number). Same question if I remove a field, what happens.
In standard java serialisation this is all documented here..
http://docs.oracle.com/javase/7/docs/platform/serialization/spec/version.html
But I cant find the equivalent information for flexjson, that deals explicitly with the issues surrounding versioning of objects, Is there any?
Cheers,
Phil.
Flexjson will look at the JSON first to find any fields it contains, and then looks for those fields on the Object you are deserializing into. So adding new fields to an object will not cause the deserialization process to fail. The new field will just not be populated from the JSON object (ie it will retain the value(s) set in the constructor or the initialization values).
If you remove a field from an object in the future Flexjson will simply not deserialize that value into the object because it won't find a setter for it.
So you can think about the getter/setter functions as a declaration on the JSON of what you want out of it. You aren't required to serialize/deserialize all values from the JSON object.
The only part that gets really tricky is if you rename fields, or change types on a field. Renaming field can be handled by keeping the older setter around and internally setting the new field in that older setter. You can mark it private or protected to hide it from the outside and Flexjson will still use it. If you change the type it is much more tricky. One option is to keep the older setter with the prior type around (like setFoo(String) and setFoo(List)) and adapt to the new type. The other option is to write your ObjectFactory to translate between to the two potential types. This of course is the hardest to do. The last option is don't do this without changing the name of the field, and use one of the other methods to translate.

Serialization of Objects

how does Serialization of objects works? How object got deserialized and a instance is created from serialized date without a call to any constructor?
I've kept this answer language agnostic since a language wasn't given.
When the object is serialized, all the require information to rebuild it is encoded in way which can be retrieved. This typically includes the type of the object, as well as the value of all the instance variables.
When the object is deserialized, an area in memory of the correct size is allocated and is populated using the serialized information such that the new object is identical to the serialized one.
The running program can then refer to this new object in memory without having to actually call the constructor.
There are lots of little details which this doesn't explain, but this is the general idea of serialization/deserialization.
Are you talking about Java? If so, serialization is an extralingual object creation mechanism. It's a backdoor that uses native code to create the object without calling any constructors. Therefore, when designing a class for serializability, you need to make sure that a class created through deserialization maintains the same invariants (key fields being initialized) as you would through the constructor path. A third way to create objects in Java is through cloning, and similar issues apply.
Cloning and serialization don't interact well with the use of final fields if you need to set the value of that field to something different than what is returned by clone or the deserialization process.
Josh Bloch's "Effective Java" has some chapters that explain these issues in more depth.
(this answer may apply to other languages too, but I've only used serialization in Java)
Regarding .NET: this isn't a definitive or textbook answer, and I might be all-out wrong...
.NET Serialization needs to be seperated out into Binary vs. others (XML or an XML derivitave typically). Binary serialization is mostly a black-box to me, but it allows the object to be serialized and restored in their current state. XML serialization typically only serialized the public fields/properties of an object, unless overriden by adding a custom ISerializable implementation.
In the case of XML serialization I believe .NET uses Reflection to determine which fields and properties get converted to their equivalent Elements. Adding an [XMLSerializable] attribute will implement a default behavior which can be adjusted by applying other attributes at the field level (such as [XMLAttribute]).
The metadata (which Reflection depends on) stores all the object members as well as their attributes and addresses, which allows the serializer to determine how it should build the output.

Will the VB.Net Serializers execute code in public members?

We wish to use the Binary Formatter. In debugging, thus far, it seems that it does not execute the getters for public properties. Does the XML Serializer behave the same way? Also, during deserialization, will the deserializers use the setters to apply the values during deserialization?
Thus far, our testing with BinaryFormatter shows that it simply writes directly to and from member variables. It does not step through any of the getters or setters. Is the XML Serializer the same way?
What if a public property did something silly like Random().Next? Will this be serialized by the Binary Formatter? It seems that with the XML Serializer, you would need to decorate this member appropriately to get it to participate. The Binary Formatter seems to only work, again, on member variables.
Thanks.
You need both a getter and a setter or the property will not be serialized. The reason for this is that the serializer assumes it can't set the value so transporting it would be wasteful.
You can even have an empty setter and it will work.
I just ran a quick test using the XML Serializer. To answer your question: Yes, it does use the getters durning serialization and it does use the setters during deserialization.
EDIT
Found this in the docs:
This example uses a binary formatter to do the serialization. All you need to do is create an instance of the stream and the formatter you intend to use, and then call the Serialize method on the formatter. The stream and the object to serialize are provided as parameters to this call. Although it is not explicitly demonstrated in this example, all member variables of a class will be serialized—even variables marked as private. In this aspect, binary serialization differs from the XMLSerializer Class, which only serializes public fields. For information on excluding member variables from binary serialization, see Selective Serialization.
Think about it this way:
Let's say you're deserializing a class with several serialized properties, and the setter for the last property has side effects that can alter the values of another property. The altered property no longer reflects your serialized data. Do you really want it to use that setter?
On the other hand, what if there is no backing store for a property? Perhaps it's a composite property allowing you to get and set values of all the others at once. Arguably this property shouldn't be serialized (or only this property should be serialized, depending on how things work), but there could be other examples. How does the formatter know where to assign the value for such a property?
So which is it? I had to look it up and couldn't quickly find an authoritative source, but it looks like the XmlSerializer does use getters and setters while the BinaryFormatter does not use getters or setters.
And that kind of makes sense. My first point showed that you don't really want to use getter/setters. My 2nd point showed that you may have to use them. The binary formatter can just take the exact in-memory representation of the object, so it skips the getter/setters. The XmlSerializer, which doesn't have this ability, has to use the other method.
You should probably set up a quick test project for yourself so you can see it in action.