I'm using Java jackson for dynamic serialization and deserialization to/from json.
I want to have a custom annotation #JsonDebug, which will basically turn on/off the serialization of
field etc. depending on a static variable debugMode. The idea is that if an enum key is tagged with the annotation,
it shouldn't be useable while serialization/deserialization process is on.
The problem is that the only way I find doing it is by either implementing custom serializer/deserializer for the enum I want, which is not a general solution or by overriding the existing Enum serialization/deserialization process which is kind of a overkill for a single annotation processing. I tried using AnnotationIntrospector and override behavior of hasIgnoreMarker which is the way it works for fields, but it doesn't ignore enum keys. I thought mixin annotations might be the way to go, but they only work for specified classes with specified field names. I found out that even with ignore annotations on keys, they still serialize/deserialize to/from json.
.
Related
I'm using Kryo for creating game-saves in code I'm working on.
Using the default serializer, FieldSerializer, I serialize one massive POJO.
It's a class that contains other classes I've created and primitive types.
The entire state of my game world is saved and loaded completely correct without creating any custom serializers.
Are not all class trees originally built up from primitive data
types?
Why would you need any other serializer?
The only thing I can think of is improving disk space or speed of serialization/deserialization.
Yes, in a perfect world, you should only serialize pojos, and pojos should be a 'tree of primitives data types'.. But it's not so easy.
In order to be fast, Kryo doesn't use java serialization by default. It have his own serializer, FieldSerializer, which introspect instances and serialize it fields by fields. This serializer doesn't use default method like readResolve writeReplace, and fail to restore some objects behaviors.
For example, imagine a simple POJO, which own a Date property. This "primitive datatypes" doesn't have any field serializable (there are all marked as transient) : his serialization process is done through readObject or writeObject : The default FieldSerializer will not work.
If your POJO has a collection property, and you create an instance with Collections.emptyList(), then this can work.. or not : The "emptyList" collection should be a singleton, and this behavior is done through a readResolve method. The FieldSerializer doesn't know about it.
Kryo come with a set of defaults serializers which can handle this kind of types, but sometimes, you have to create your own to handle a class with a particular behavior. But usually, you create a serializer in order to improve the speed of classes which you serialize often, not because Kryo is not able to serialize them.
Kryo come with a special serializer, JavaSerializer or ExternalizableSerializer which use the default java serialization but they prevent Kryo to "see" inner fields and you loose all the benefits of using Kryo.
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.
Ideally, it would look much like this:
List<String> props = objectMapper.getKnownProperties(MyPojo.class);
Alas, there is no such method. An approach that would generally work is to explicitly set Include.ALWAYS as the ObjectMapper's default, instantiate an instance of the class reflectively, convert it to a map, and examine the keyset. However, classes can still override the ObjectMapper's include behavior given annotations.
Is there a more elegant approach? At the very least, is there a way to override class annotations using the object mapper?
Edit:
Just to clarify, these pojos/javabeans/DTOs are designed for use with Jackson and are already rigged with annotations to result in specific serialization behavior. It just so happens that I need to dynamically know what I might end up with up-front, ideally without duplicating the information already available to jackson. That said, if another framework offers this functionality, I'd be curious to know. :)
With Jackson, you can introspect a class and get the available JSON properties using:
// Construct a Jackson JavaType for your class
JavaType javaType = mapper.getTypeFactory().constructType(MyDto.class);
// Introspect the given type
BeanDescription beanDescription = mapper.getSerializationConfig().introspect(javaType);
// Find properties
List<BeanPropertyDefinition> properties = beanDescription.findProperties();
If you have #JsonIgnoreProperties class level annotations, check this answer.
Depending on your exact needs, JsonFilter could also work (f.ex see http://www.cowtowncoder.com/blog/archives/2011/09/entry_461.html).
And for more advanced cases, BeanSerializerModifier does give you access to actual list of BeanPropertyWriters, which represent individual properties POJO has. From that, you could write a wrapper that enables/disables output dynamically.
Or perhaps you can even combine approaches: modifier to get list of possible property names; then FilterProvider to dynamically add filter. Benefit of this would be that it is a very efficient way of implementing filtering.
It's possible to ignore all annotations by using a dummy AnnotationIntrospector:
objectMapper.setAnnotationIntrospector(new AnnotationIntrospector(){
#Override public Version version() {
return Version.unknownVersion();
}
});
Perhaps you could use Jackson's JSON Schema module to generate a schema for a class, then inspect the schema.
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.
JAXB works well until I need to do something like serialize beans for which I cannot modify the source. If the bean doesn't have a default constructor or if it refers to objects I want to mark transient then I'm stuck writing a separate bean which I can annotate and then manually copy the information over from the other bean.
For instance, I wanted to serialize exception objects, but found that the only way to do that was use a hack that required using com.sun.* classes.
So, what alternatives are there? What's the next most popular xml serializing api? It would be nice to be able to do things like:
Choose at serialization time whether to include certain fields in the result. (marking things transient when running the serializer).
Handle loops in the object graph by using references or something other than just dying.
Perhaps annotate an object so that in version 1 it serializes things in one way and in version 2 it serializes them in another. Then when serializing I just choose which version of the object ot serialize.
Have a way to generate XSDs from annotations on an object.
Basically I just want more flexibility than I currently have with JAXB.
Well the standard answer for wanting a uber configurable serialisation framework is xstream.
JAXB is a spec, so you can pick from different implementations. EclipseLink JAXB (MOXy) has extensions for what you are asking:
Externalized Metadata
Useful when dealing with classes for which you cannot annotate the source or to apply multiple mappings to an object model.
http://bdoughan.blogspot.com/2010/12/extending-jaxb-representing-annotations.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/EclipseLink-OXM.XML
XPath Based Mapping
For true meet-in-the-middle OXM mapping:
http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html
http://bdoughan.blogspot.com/2011/03/map-to-element-based-on-attribute-value.html
http://bdoughan.blogspot.com/2010/07/xpath-based-mapping.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted/MOXyExtensions
JPA Compatibility
Including support for bi-directional relationships.
http://bdoughan.blogspot.com/2010/07/jpa-entities-to-xml-bidirectional.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA
Also look at JIBX. It's a good xml<->object mapper. My experience is though that if your objects have a somewhat funky relationships it's often easier to create a wrapper object that hides that complexity and then map that object with JIBX.
XStream is a popular XML serialisation library that claims to be able to serialize just about anyting, regardless of constructors or other problems (even deserialize final fields). Give it a try.
Requires no modifications to objects. Serializes internal fields, including private and final. Supports non-public and inner classes. Classes are not required to have default constructor.