I am trying to send a collection of diffrent objects to server which accepts Json objects. Figuring out which is the optimal way to do this.
Plan A:
Serialize a collection of objects, like this:
ArrayList<Object> objects = new ArrayList<>();
objects.put(new Human("Johhny"));
objects.put(new Cannon(13));
objects.put(new Hamburger(1.3));
String json = Utils.getObjectMapper().writeValueAsString(objects);
Serialization works fine, and when I must deserialize, I receive array of Objects too (linked hash maps, to be precise). The problem is, I don't know which of these are Human, Cannon or Hamburger.
Is there any way to put object's class name into json, so when it's deserialized, the object mappers knows which class to use?
Plan B:
Parse each LinkedHashMap, manually determine it's true Class based on properties, and manually deserialize into object
Plan C:
Put each type of objects into diffrent collection with specific type.
Serialize three collections and combine them into one string with specific splitter
Deserialize back in reversed order.
The solution is:
Simply add mapper setting before writing to string: Utils.getObjectMapper().enableDefaultTyping(ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT).writeValueAsString(objects);
Thanks to #dmitry-zvorygin!
Polymorphic (de)serialization is all you need -
https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization
Just make sure you have base class for all the entities.
Related
In Python i have a class with some string attributes and a function that returns an object of this class with atttributes set (sometimes can return an array of objects).
Theres any way to get this return in Java? Where i can see the strings of the object?
I Tried Jython but couldnt make it work!
Use json.dump function in Python to serialize your object into json format. Then use something like json.org library in Java to parse this object into Java object, some example over here.
Mind that not every object might be serializable, in general data structures like dictionaries or lists are easily serializable, from your description it seems like you want to move an instance of an object from one program into another, which is not possible to be done automatically and requires human work in rewriting the code as instances of classes contain not only data but also functions (methods).
Good luck!
I have implemented some REST API with springMVC+Jackson+hibernate.
All I needed to do is retrieve objects from database, return it as a list, the conversion to JSON is implicit.
But there is one problem. If I want to add some more information to those object before return/response. For example I am returning a list of "store" object, but I want to add a name of the person who is attending right now.
JAVA does not have dynamic type (how I solve this problem in C#). So, how do we solve this problem in JAVA?
I thought about this, and have come up with a few not so elegant solution.
1. use factory pattern, define another class which contain the name of that person.
2. covert store object to JSON objects (ObjectNode from jackson), put a new attribute into json objects, return json objects.
3. use reflection to inject a new property to store object, return objects, maybe SpringMVC conversion will generate JSON correctly?
option 1 looks bad, will end up with a lot of boiler plate class which doesn't really useful. option 2 looks ok, but is this the best we could do with springMVC?
option 1
Actually your JSON domain is different from your core domain. I would decouple them and create a seperate domain for your JSON objects, as this is a seperate concern and you don't want to mix it. This however might require a lot of 1-to-1 mapping. This is your option 1, with boilerplate. There are frameworks that help you with the boilerplate (such as dozer, MapStruct), but you will always have a performance penalty with frameworks that use generic reflection.
option 2, 3
If you really insist on hacking it in because it's only a few exceptions and not a common pattern, I would certainly not alter the JSON nodes or use reflection (your option 2 and 3). This is certainly not the way to do it in Java.
option 4 [hack]
What you could do is extend your core domain with new types that contain the extra information and in a post-processing step replace the old objects with the new domain objects:
UnaryOperator<String> toJsonStores = domainStore -> toJsonStore(domainStore);
list.replaceAll(toJsonStores);
where the JSONStore extends the domain Store and toJsonStore maps the domain Store to the JSONStore object by adding the person name.
That way you preserve type safety and keep the codebase comprehensive. But if you have to do it more then in a few exceptional cases, you should change strategy.
Are you looking for a rest service that return list of objects that contain not just one type, but many type of objects? If so, Have you tried making the return type of that service method to List<Object>?
I recommend to create a abstract class BaseRestResponse that will be extended by all the items in the list which you want return by your rest service method.
Then make return type as List<BaseRestResponse>.
BaseRestResponse should have all the common properties and the customized object can have the property name as you said
My java application makes use of complex object graphs that are jackson annotated and serialized to json in their entirety for client side use. Recently I had to change one of the objects in the domain model such that instead of having two children of type X it will instead contain a Set<X>. This changed object is referenced by several types of objects in the model.
The problem now is that I have a large quantity of test data in json form for running my unit tests that I need to convert to this new object model. My first thought for updating the json files was to use the old version java object model to deserialize the json data, create new objects using the new version object model, hydrate the new objects from the old objects and then finally serialize the new objects back to json. I realized though that the process of programmatically creating matching object graphs and then hydrating those object graphs could be just as tedious as fixing the json by hand since the object graphs are relatively deep and its not a simple clone.
I'm wondering how I can get around fixing these json files entirely by hand? I'm open to any suggestions even non-java based json transformation or parsing tools.
One possibility, if Objects in question are closely-enough related, structurally, is to just read using one setting of data-binding, write using another.
For example: if using Jackson, you could consider implementing custom set and get methods; so that setters could exist for child types; but getter only for Set value. Something like:
```
public class POJO {
private X a, b;
public void setA(X value) { a = value; }
public void setB(X value) { b = value; }
public X[] getValues() {
return new X[] { a, b };
}
```
would, just as an example, read structure where POJO would have two Object-valued properties, "a" and "b", but write structure that has one property "values", with JSON array of 2 Objects.
This is just an example of the basic idea that reading in (deserialization) and serialization (writing out) need not be symmetric or identical.
I am working in Java. I have an class called Command. This object class stores a variable List of parameters that are primitives (mostly int and double). The type, number, and order of parameters is specific to each command, so the List is type Object. I won't ever query the table based on what these parameter values are so I figured I would concatenate them into a single String or serialize them in some way. I think this may be a better approach that normalizing the table because I will have to join every time and that table will grow huge pretty quickly. (Edit: The Command object also stores some other members that won't be serialized such as a String to identify the type of command, and a Timestamp for when it was issued.)
So I have 2 questions:
Should I turn them into a delimited String? If so, how do I get each object as a String without knowing which type to cast them to? I attempted to loop through and use the .toString method, but that is not working. It seems to be returning null.
Or is there some way to just serialize that data of the array into a column of the DB? I read about serialization and it seems to be for the context of serializing whole classes.
I would use JSON serializer and deserializer like Jackson to store and retrieve those command objects in DB without losing the specific type information. On a side note, I would have these commands implement a common interface and store them in a list of commands and not in a list of objects.
I have a class structure that I would like to serialize with Xstream. The root class contains a collection of other objects (of varying types). I would like to only serialize part of the objects that are stored in the collection (primarily their IDs, and not the remaining contents of each element).
Anyone have an idea of how I might go about this?
Thanks
You can specify that all the collection element fields except for ID should not be serialized by either:
Declaring them transient
Annotating them with #XStreamOmitField
Calling xstream.omitField()
Or you can write your own converter.