Ajax call with Jackson marshaling of subclasses (Spring MVC) - java

I have a controller that receives an abstract class.
This class has 3 different subclasses.
In order for the controller to receive the ajax call i must add a "#class" : com.my.project.my.Class
parameter to the object i'm sending.
This feels really bad to implement.
Is there any other ways to send the subclasses and avoiding forcing the client to pass an actual class name with each call.
Thanks

Jackson has its own inheritance handling mechanism. You don't necessarily need to use #class. See here.
This feature cannot be the cleanest. Jackson does its deserialization through hints from the developer. Notice how you always pass a Class or TypeReference object when interacting with its ObjectMapper. In the same way, the JSON needs to contain hints for which subtype to deserialize to.

Related

Gson how to deserialize when the concrete implementation type is unkown

Let's say I've go an interface Request with an void handle(); method (pretty much like a command pattern). I've got several implementations of this interface. My application will receive serailized Request objects, but as far as I am concerned I have to tell the gson deserializer a concrete class, so ConcreteRequest (which implements Request) for example. The JSON for all of them looks exactly the same, so how do I decide which class I have to cast it to? Is there any specific way to do this automatically or any workaround?

Downcasting in Java ? Is this a downcasting issue at all?

So I have a POJO class let´s call it: InnerDomainObject.
Then I have an object representing this object, with a few more fields, for communication towards different clients (it s an API DTO): OuterDomainObject
Because the DTO has in fact all of the POJOs fields, I made OuterDomainObject inherit from InnerDomainObject.
Now I need to somehow cast InnerDomainObject to OuterDomainObject --> not possible.
I want to avoid writing a constructor iterating through all the fields.
I want to avoid writing useless code.
I just want OuterDomainObject to be created out of InnerDomainOBject´s values and then add some to it before sending it to the client.
What´s the best way of doing this ?
You sound like you are using the Adapter Pattern. You shouldn't need to cast an InnerDomainObject to an OuterDomainObject. You should use composition: the OuterDomainObject should hold a reference to an InnerDomainObject, which will likely be passed into a constructor. When a client invokes a method on an OuterDomainObject, if that method exists in InnerDomainObject, the OuterDomainObject should call that method on its instance of InnerDomainObject. Instead of casting an InnerDomainObject foo to an OuterDomainObject, just create a new OuterDomainObject and pass in foo: new OuterDomainObject(foo). You will need to write some simple glue code, but the result is very clean.

Serializing objects with flexjson

I am trying to use flexjson library. But in my object I have to use:
com.google.api.client.util.DateTime which do not have no parameters constructor. I always get NoSuchMethodException with message: Flexjson will instantiate any protected, private, or public no-arg constructor. I have sources and trying to do something with that, here is the code:
constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
return constructor.newInstance();
Exception is being thrown in clazz.getDeclaredConstructor() due to lacking empty constructor. What is the best approach to find constructor with let's say those signature:
DateTime(long timestamp)?
Have anyone encounter this kind of problem with this library? Maybe you can suggest to use other one. I am using it to serialize objects generated by Google Cloud Endpoints. Maybe I can do that with different approach?
You don't have to change the source code of Flexjson to do this. The way to handle this is to create your own implementation of ObjectFactory and register that for the type you are binding into. From there you can instantiate it however, you desire. It's easiest to subclass BeanObjectFactory and override the method instantiate(). In there you can do whatever you want to create an instance of an object you wish. By subclassing BeanObjectFactory it will take care of binding the individual properties from the JSON into your object using the setter/getter of that object. If your object doesn't support property methods you might find it easier to implement ObjectFactory and manually setting the values on that object from the JSON. There is lots of documentation on the Flexjson website about building ObjectFactories.
Then you can register your ObjectFactory to that data type using:
new JSONDeserializer<SomeObject>()
.use( DateTime.class, new DateTimeObjectFactory() )
.deserialize(json);

Exclude datamember when using renderJSON with play framework

I need to render objects in JSON and send them to the client but I need to exclude fields like email and password for obvious reasons.
I know play uses GSON (by google?) and you can pass a serializer class when calling the renderJSON() method. However I'm rendering different types of classes at once using a container class:
public class JSONContainer {
public List<User> userList;
public List<Toy> toyList;
}
For each class it's possible to make a Serializer class implementing GSON's JsonSerializer<...> method. But if I render a JSONContainer object like this: renderJSON(container) how can I pass the serializer classes to the rendering method?
Or is there maybe an easier/better way to do this?
Take a look at this post, which gives you a couple of options.
It would appear that the best option is to the #Expose (com.google.gson.annotations.Expose) annotation to mark the fields that you want to be serialised by Gson. You then need to use the GsonBuilder to specifically only include the #Expose fields.
Alternatively, as you have mentioned in your post, you can simply build your serialisations yourself. If you look at this post, it shows how specific class types are registered against the GsonBuilder, so any object of that found as part of the serialisation will use your specific serialiser.

How to unwrap the original object from a dynamic proxy

what's the best approach to unwrap a dynamic proxy to retrieve the original object beneath?
The dynamic proxy has been created using java.lang.reflect.Proxy.newProxyInstance()
Thank you.
There's no good method: Proxy.getInvocationHandler(proxy) returns handler, but the problem is to extract the original object from the handler. If your handler is an anonymous class, the only way to extract original object is to use reflection and extract original from field named val$something - very ugly method.
Better way is to create non-anonymous handler class with a getter, then you do:
((YourHandler)Proxy.getInvocationHandler(proxy)).getOriginalObject()
Each proxy has an InvocationHandler associated with it. Only the InvocationHandler knows which object (if any) underlies the proxy. If you control the creation of the proxy, then you can supply your own InvocationHandler that will have the extra functionality that you desire (i.e. will be able to disclose the underlying object.) If you don't, then I am afraid you're out of luck.
You can use the Proxy.getInvocationHandler(proxy) method to obtain the original InvocationHandler.

Categories