Serialize legacy nested Java Code to Json - json

Looking for some help to serialize a deep nested java objects to Json. The constraint is that I cannot add any annotations or change the current Java code. Looking for a powerful Json library which has configuration options to convert Java to Json without altering the Java Object themselves. Following would be some of the options that might be required
Specify include/exclude fields/methods. Should be able to specify this at nested levels. A is composed of B and B is composed of C. Should have ability to specify include/exclude at C.
Include/Exclude Objects at nested levels.
Rename fields from java properties while converting to Json (at nested level objects too)
Manager circular dependencies.
Was looking at Jackson and Gson for this requirements. While there are tons of options using annotations to specify serialization configs while writing new Java Pojo's, I am looking at options where I need to specify serialization properties without changing the current Java code. Jackson and Gson do seem to have options for these, but not documented in depth.
Which library is easier to configure for the above requirements? Any other powerful library other than Jackson/Gson? Any pointers to this will be of great help.
Thanks much for your time.

As to Jackson, you might consider using so-called mix-in annotations (see f.ex http://www.studytrails.com/java/json/java-jackson-mix-in-annotation.jsp) which allow you to specify mix-ins to use, without adding them directly in the legacy classes.
This would let you use annotation-based configuration, but leave actual classes untouched.
But given all of your requirements, it may perhaps be better to just use Tree Model of Jackson or GSON (get JsonNode or such), and manually handle conversions to your liking.
You may then be able to convert tree value into POJO; Jackson, for example, has method(s) for doing this (ObjectMapper.treeToValue(), .valueToTree(), .convertValue()) which allow conversions of structurally compatible representations.

Related

How to use the Jackson object mapper with Java 17

I'm trying to implement a logic that serializes and de-serializes a very complex legacy object. The object contains other complex objects inside of it that are spread through various other projects. There are even some JAXB1 objects that are generated from an xsd schemas and are part of the chain.
Right now there is already a working version that uses XStream and this worked for years. But since Java 17 there are issues because of the new restriction for using reflection on private fields from different modules. Exceptions like this started to appear ->
Module {A} does not 'opens {package}' to {B}". One of the things that bothers me is that all of these packages are from some third party libs and I even can't find any objects from them in the model chain.
So I started implementing a new serialization based on the Jackson databind API but right now I'm wondering is it going to solve the issues at all? Does Jackson also use reflection in case to serialize and de-serialize? What is the best way to configure the ObjectMapper and what should I change in the objects that I need to work with in case to make the reflection usage as low as possible?
Right now I've configure the ObjectMapper as:
objectMapper.disable(MapperFeature.AUTO_DETECT_CREATORS,
MapperFeature.AUTO_DETECT_FIELDS,
MapperFeature.AUTO_DETECT_GETTERS,
MapperFeature.AUTO_DETECT_IS_GETTERS);
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
and I'm annotating all fields that should be serialized with #JsonProperty but I'm not sure that this is going to help. Okay, I assume I must have getters and setters, but should I also annotate them? Does the annotation has something to do with the reflection usage at all?

Automatic library generation for JSON

Is there a tool like Google's Protobuf for JSON? I know you can convert from a Protobuf format to JSON but that requires a whole lot of extra serialization/deserialization, and I was wondering if there is some kind of tool that lets you specify the structure of a JSON message and then automatically generates libraries for use in a specified language (direct serialization/deserialization not just a wrapper around Protobuf's JSON formatter class)
I know nearly all languages provide their own in house way of handling JSON, and many higher level ones even allow you to avoid the boiler plate parsing code, but I was looking for a universal tool where you would only need to specify the format once, and then just get the generated libraries for use in multiple languages.
The Protobuf equivalent would be JSON-Schema, but still is language dependent on having a serializer or code generator available, just as Protobuf is.
If you're looking at making a REST-API, then OpenAPI Spec + swagger-codegen could be an option.

Attributes on protocol buffer generated types

I have some C# classes generated by protoc, in project A. I'm consuming these classes in project B. Project B serializes/deserializes to JSON using Newtonsoft.Json (for CosmosDB). There's currently an issue in the microsoft.azure.documentdb.core 1.9.1 release which prevents controlling the (de)serialization of models with any method except decorating the model properties with attributes (e.g JsonProperty). In short, I need Newtonsoft.Json to use camel casing for property names and the only way I can do that (that I know of) is to decorate the generated protocol buffer models with [JsonProperty("myProp")].
The types are fairly large and I'd rather not do this manually if possible. My hope is there's a way to tell protoc to generate the classes with custom attributes on the properties?

Parse JSON with Interface/trait and Different implementations

Currently I'm using lift-json to parse json into objects. This is the signature I generally use
net.liftweb.json.parse(json).extract[MyClass]
This is working fine. However, I'm looking to do a little more. Lets say My class has an object of type List[SomeTrait] where SomeTrait is a trait. And I have two different implementations of that trait with the different constructor signatures, but obviously implementing the same methods differently.
Is there a way in either the JSON or the code that will detect which implementation it should use? Such that, the code parsing the json can remain the same but I can continue to add new implementations of SomeTrait
There's no easy way to do that in Lift, as far as I know. You still need to have some attribute to be able to provide the type information about the JSON object itself, so the deserializer will be able to pick up the proper instance.
I'd use Jackson JsonTypeInfo annotation in order to mark subclasses and then use it's ObjectMapper to do the job.
Look https://github.com/FasterXML/jackson-annotations#handling-polymorphic-types for more details.

Jackson support for polymorphism without annotations and dedicated bean fields

Is there a way to perform serialization/deserialization in Jackson of polymorphic classes w/out using annotations or specialized bean fields? I have to support class hierarchies that I cannot modify and don't wish to use annotations.
I'd like to be able to designate a synthetic name, which would not be in the classes that I am serializing/deserializing, that would be inserted into the JSON representation and used to identify the type.
If mix-ins are not to your liking, there isn't anything pre-defined to pass, but you can relatively easily achieve this by sub-classing JacksonAnnotationIntrospector and configure mapper with it.
In your implementation you can override all aspects of annotation access: in your case it's probably enough to override findTypeResolver() (and if you want per-property overrides, 'findPropertyTypeResolver()').
The method can then use whatever mechanism you want to construct TypeResolverBuilder (most likely StdTypeResolverBuilder) that contains same information as what would usually come from #JsonTypeInfo annotation.
For anyone looking for polymorphic json unmarshaling problems, you should check out this post, which gives great examples & workarounds for JSON serialization / deserialization caveats.
And if mixins (step 5 at the above mentioned post) is not what you're looking for than go for the accepted answer by StaxMan.