NOTE: it is recommended that custom serializers extend {@link com.fasterxml.jackson.databind.ser.std.StdSerializer} insteadof this class, since it will implement many of optional methods of this class.
If serializer is an aggregate one -- meaning it delegates handling of some of its contents by using other serializer(s) -- it typically also needs to implement {@link com.fasterxml.jackson.databind.ser.ResolvableSerializer}, which can locate secondary serializers needed. This is important to allow dynamic overrides of serializers; separate call interface is needed to separate resolution of secondary serializers (which may have cyclic link back to serializer itself, directly or indirectly).
In addition, to support per-property annotations (to configure aspects of serialization on per-property basis), serializers may want to implement {@link com.fasterxml.jackson.databind.ser.ContextualSerializer}, which allows specialization of serializers: call to {@link com.fasterxml.jackson.databind.ser.ContextualSerializer#createContextual}is passed information on property, and can create a newly configured serializer for handling that particular property.
If both {@link com.fasterxml.jackson.databind.ser.ResolvableSerializer} and{@link com.fasterxml.jackson.databind.ser.ContextualSerializer}are implemented, resolution of serializers occurs before contextualization.
The {@link #serialize(Object,ConnectorTracker)} and{@link #deserialize(Type,JsonValue,ConnectorTracker)} methods must besymmetric so they can be chained and produce the original result (or an equal result).
Each {@link JSONSerializer} implementation can handle an object of a singletype.
This is the server side interface, see com.vaadin.client.communication.JSONSerializer for the client side interface. @since 7.2 @author Vaadin Ltd
Let's go through a simple example:
JSONSerializer serializer = new JSONSerializer(); return serializer.serialize( person );
What this statement does is output the json from the instance of person. So the JSON we might see for this could look like:
{ "class": "com.mysite.Person", "firstname": "Charlie", "lastname": "Rose", "age", 23 "birthplace": "Big Sky, Montanna" }
In this case it's look like it's pretty standard stuff. But, let's say Person had many hobbies (i.e. Person.hobbies is a java.util.List). In this case if we executed the code above we'd still getTransformer the same output. This is a very important feature of flexjson, and that is any instance variable that is a Collection, Map, or Object reference won't be serialized by default. This is what gives flexjson the shallow serialization.
How would we include the hobbies field? Using the {@link JSONSerializer#include}method allows us to include these fields in the serialization process. Here is how we'd do that:
return new JSONSerializer().include("hobbies").serialize( person );That would produce output like:
{ "class": "com.mysite.Person", "firstname": "Charlie", "lastname": "Rose", "age", 23 "birthplace": "Big Sky, Montanna", "hobbies", [ "poker", "snowboarding", "kite surfing", "bull riding" ] }
If the hobbies field contained objects, say Hobby instances, then a shallow copy of those objects would be performed. Let's go further and say hobbies had a List of all the people who enjoyed this hobby. This would create a circular reference between Person and Hobby. Since the shallow copy is being performed on Hobby JSONSerialize won't serialize the people field when serializing Hobby instances thus breaking the chain of circular references.
But, for the sake of argument and illustration let's say we wanted to send the people field in Hobby. We can do the following:
return new JSONSerializer().include("hobbies.people").serialize( person );
JSONSerializer is smart enough to know that you want hobbies field included and the people field inside hobbies' instances too. The dot notation allows you do traverse the object graph specifying instance fields. But, remember a shallow copy will stop the code from getting into an infinte loop.
You can also use the exclude method to exclude fields that would be included. Say we have a User object. It would be a serious security risk if we sent the password over the network. We can use the exclude method to prevent the password field from being sent.
return new JSONSerialize().exclude("password").serialize(user);
JSONSerializer will also pay attention to any method or field annotated by {@link flexjson.JSON}. You can include and exclude fields permenantly using the annotation. This is good like in the case of User.password which should never ever be sent through JSON. However, fields like hobbies or favoriteMovies depends on the situation so it's best NOT to annotate those fields, and use the {@link JSONSerializer#include} method.
In a shallow copy only these types of instance fields will be sent: String, Date, Number, Boolean, Character, Enum, Object and null. Subclasses of Object will be serialized except for Collection or Arrays. Anything that would cause a N objects would not be sent. All types will be excluded by default. Fields marked static or transient are not serialized.
Includes and excludes can include wildcards. Wildcards allow you to do things like exclude all class attributes. For example *.class would remove the class attribute that all objects have when serializing. A open ended wildcard like * would cause deep serialization to take place. Be careful with that one. Although you can limit it's depth with an exclude like *.foo. The order of evaluation of includes and excludes is the order in which you called their functions. First call to those functions will cause those expressions to be evaluated first. The first expression to match a path that action will be taken thus short circuiting all other expressions defined later.
Transforers are a new addition that allow you to modify the values that are being serialized. This allows you to create different output for certain conditions. This is very important in web applications. Say you are saving your text to the DB that could contain < and >. If you plan to add that content to your HTML page you'll need to escape those characters. Transformers allow you to do this. Flexjson ships with a simple HTML encoder {@link flexjson.transformer.HtmlEncoderTransformer}. Transformers are specified in dot notation just like include and exclude methods, but it doesn't support wildcards.
JSONSerializer is safe to use the serialize() methods from two seperate threads. It is NOT safe to use combination of {@link JSONSerializer#include(String)}{@link JSONSerializer#transform(flexjson.transformer.Transformer,String)}, or {@link JSONSerializer#exclude(String)}from multiple threads at the same time. It is also NOT safe to use {@link JSONSerializer#serialize(Object)} and include/exclude/transform frommultiple threads. The reason for not making them more thread safe is to boost performance. Typical use case won't call for two threads to modify the JsonSerializer at the same type it's trying to serialize.
an example of produced json:
{"store":{"storeMap": {"org.reflections.scanners.TypeAnnotationsScanner":{ "org.reflections.TestModel$AC1":["org.reflections.TestModel$C1"], "org.reflections.TestModel$AC2":["org.reflections.TestModel$I3", ...
TODO Wrap reader in a CountingReader that tracks line/character index. @author gbrown
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|