Dynamic Schema & Deserialization with Protostuff - serialization

I'm using Protostuff in an attempt to serialize/deserialize objects of several different types for which no protobuf sources are available (it's a server-server RPC scenario). Serialization goes OK because I know the type of the object to serialize and can create the schema:
Schema schema = RuntimeSchema.getSchema(object.getClass());
Now, I use ProtobufIOUtil.toByteArray and get a byte array which I then pass to a remote server. However, I can't seem to deserialize this byte array in the remote server because I have no way to create a schema for an object of "unknown" type. Is there any way I can get past this and use Protostuff in the same way I would use Java's native serialization?

There are few solutions with common idea - serialize name of the class together with the data.
First one requires protostuff-runtime. You should create wrapper class with one field of type Object:
public class Wrapper {
public Object data;
}
Then you put your object to data field and serialize wrapper, protostuff-runtime will append class name to serialized form automatically, and later use it for deserialization.
If you want more control, then you can do similar thing without protistuff-runtime.
First, you need a wrapper class:
public class Wrapper {
public String clazz;
public byte[] data;
}
Then you should serialize your data to byte array, store it to wrapper, and then serialize wrapper instance.
On remote side, you deserialize Wrapper first, then get clazz field - it is the class you should use to deserialize data.

Related

How to (de)serialize an instance of a generated data class

I need to (de)serialize to and from JSON some of the data classes that are generated by a Gradle plugin. Normally I would just use a library like Moshi or kotlinx.serialization and add the proper annotation to the class I want to serialize but, since this data classes are autogenerated, this is a problem.
I would like to avoid manually to map all the fields of the generated data class to some other class that I can (de)serialize, or to write a custom adapter for all these data class so, I was wondering if there is another way to tell, for example, kotlinx.serialization that a class is #Serializable without having to put the annotation directly on top of the class itself.
Or, alternatively, is there a better way to convert to and from a string an instance of a generated data class?
kotlinx.serialization supports generating serializers for 3rd party classes. We need to use forClass parameter in #Serializer, for example:
data class MyData(val data: String)
#Serializer(forClass = MyData::class)
object MyDataSerializer
fun main() {
val data = MyData("foo")
println(Json.encodeToString(MyDataSerializer, data))
}
You can read more in the official documentation: https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/serializers.md#deriving-external-serializer-for-another-kotlin-class-experimental

Need of serialization

I'm new to serialization concept, please help in understanding concept.
What exactly serialization means? I have read the definition, but could not understand in details.
How basic types (int, string) are serialized?
If we don't use serialization in our code how data will be transmitted?
Is there any implicit serialization process involved while accessing database from front end Java/C# code? example insert/delete from database.
Serialization just takes an object and translates it into something simpler. Imagine that you had an object in C# like so:
class Employee
{
public int age;
public string fullname;
}
public static void Main()
{
var john = new Employee();
john.age = 21;
john.fullname = "John Smith";
var matt = new Employee();
matt.age = 44;
matt.fullname = "Matt Rogers";
...
This is C# friendly. But if you wanted to save that information in a text file in CSV format, you would end up with something like this:
age,fullname
21,John Smith
44,Matt Rogers
When you write a CSV, you are basically serializing information into a different format - in this case a CSV file. You can serialize your object to XML, JSON, database table(s), memory or something else. Here's an example from Udemy regarding serialization.
If you don't serialize, confusion will be transmitted. Perhaps your object's ToString() will be implictly called before transmission and whatever result gets transmitted. Therefore it is vital to convert your data to something that is receiver friendly.
There's always some serialization happening. When you execute a query that populates a DataTable, for example, serialization occurred.
Concept :
Serialization is the process of converting an object into series of bytes.
Usually the objects we use in application will be complex and all of them can be easily represented in the form of series of bytes which can be stored in the file/database or transfered over network.
You can make a class Serializable just by making it implement Serializable interface.
For a class to be serialized successfully, two conditions must be met:
The class must implement the java.io.Serializable interface.
All of the fields in the class must be serializable. If a field is not serializable, it must be marked transient.
When the program is done serializing, and if it is stored in a file with extension .ser then it can be used for deserializing.
Serialization gives an serialVersionUID to the serialized object which has to match for deserialization

jackson serialize referenced object fields to root

I am working on POC of jersey REST service to be consumed by js MVC framework. On one of the forms i need to return UserProfile object (serialized to JSON by Jackson) which will be used to pre-populate HTML form. On form submission only a subset of fields must be sent to server (since some fields like "role" are read-only and must not be changed) so input JSON will be mappped to UserProfileUpdateRequest object. From server-code maintenance point of view i would like to have have a relationship between these 2 objects, since UserProfileUpdateRequest will be a subset of UserProfile, so my first choice is to use composition: UserProfile contains UserProfileUpdateRequest.
The problem is that when UserProfile is serialized to JSON by jackson, all properties of referenced UserProfileRequest instance will be wrapped in userProfileRequest field- what seems to be quite natural but is not acceptable for JS guys (or at least i was told it is not acceptable). Is there any way i could force jackson to "flat" root object and point for which referenced objects its properties must be serialized under root? A little example
class UserProfileRequest{
private String a;
private String b;
...
}
class UserProfile{
private String role;
...
private UserProfileRequest userProfileRequest;
}
So when UserProfile is serialized i got:
{"role":"admin",...,"userProfileRequest":{"a":"...","b":"...",...}}
but would like to get
{"role":"admin",...,"a":"...","b":"...",...}
I am using Jackson 1.9.7.
I think you are looking for the #JsonUnwrapped annotation.
class UserProfile{
private String role;
...
#JsonUnwrapped
private UserProfileRequest userProfileRequest;
}
Edit: Here is the link to #JsonUnwrapped in Jackson 1.9.9, so it should be available in 1.9.7, too.

Complex objects at settings. Serializing issue

Default settings serializer supports only simple types. How should I save complex classes. For example:
public class User
{
public string Name {get;set;}
public int Age {get;set;}
}
Now I have to save each field of complex object as separate setting to make it work.
Please advise
The easiest approach is to serialize your settings object and store it as a string. I would recommend JSON.Net for doing this.
string json = Newtonsoft.Json.JsonConvert.SerializeObject(mySettings);
// do something with this string
You can then create a new object from the json
MySettingsObject mySettings = Newtonsoft.Json.JsonConvert.DeserializeObject<MySettingsObject>(json);
You can also take a look to Generic Object Storage Helper for WinRT, available at http://winrtstoragehelper.codeplex.com.
This library serializes your objects using XML format.

How to use an Eclipselink Converter to serialize a list of objects to json

I've written a implementation of Converter that uses Jackson JSON to serialize a list of deeply structured objects to JSON, but it's not being called. Am I doing this correctly?
#Converter(name="arrayList", converterClass=ArrayListJsonSerializedObjectConverter.class)
private List<DeeplyStructuredObject> deeplyStructuredObjects= new ArrayList<DeeplyStructuredObject>();
Additionally, I'd like to know whether or not one can use a ReadTransfomer in addition to a
Converter on the same property, e.g.
#Converter(name="arrayList", converterClass=ArrayListJsonSerializedObjectConverter.class)
#ReadTransformer(method="someMethod")
private List<DeeplyStructuredObject> deeplyStructuredObjects= new ArrayList<DeeplyStructuredObject>();