Jackson Deserialization of List with Default Typing - java

Good Day,
Hi All,
I'm trying to configure the Jackson Object Mapper to de-serialize any json String to my domain specific objects.
I've configured the Object Mapper as below
ObjectMapper mapper = new ObjectMapper();
mapper.configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.enableDefaultTypingAsProperty(DefaultTyping.NON_FINAL, "remoteClass");
In my domain, any json string should contain a remoteClass property which denotes the actual JAVA POJO (canonical name) that it corresponds to. The above configuration helps resolve abstract types
However with the above, now java.util.Lists are not getting properly deserialized, since they are abstract types.
I get the following error
Unexpected token (START_OBJECT), expected VALUE_STRING: need JSON String that contains type id (for subtype of java.util.List)
Object Mapper in this case is not resorting to the default collectionFallBacks
I tried other configuration to overcome the issue such as
SimpleModule module = new SimpleModule("test", Version.unknownVersion());
module.addAbstractTypeMapping(List.class, ArrayList.class);
mapper.registerModule(module);
However these lead to other problems.
Can someone please help me with the same. I've spent days on this now. This seems like a limitation in Jackson. Correct me if I'm wrong

I faced this problem recently. Try this, in your POJO, instead of defining property as
List<SimpleModule>
define it as
List<Object>.

Related

ObjectMapper default value of if some fields cannot be cast to object

I'm new to Java, so apologies if this question is not to the desired standard: I'm loading data from a flat mongodb table and would like to write all the documents into a Pojo, I'm calling it DataClass. My issue is that in some cases the type of the field is not correct. In the below code I'm using mapper.readValue to read the Json and cast it to the object. If one of the fields is wrong, the whole loop fails. Is there a way to do it element-wise and just ignore cases where there is a failure or set a default value?
List<DataClass> result = new ArrayList<>();
FindIterable<Document> documents = getCollection().find();
for (Document doc : documents) {
result.add(mapper.readValue(doc.toJson(), DataClass.class));
Any suggestions would be greatly appreciated.
I guess you are looking for,
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
This will not fail the serialization if the passed json has unknown properties.
Moreover, as per the docs,
JsonMappingException if the input JSON structure does not match structure
expected for result type (or has other mismatch issues)
You can catch JsonMappingException if you are looking in that direction.

Replacing Jackson with Boon

I'm looking to replace Jackson deserialization with Boon to test the differences in deserialization speeds. I am reading JSON from a file (which can be in the millions of lines long), consisting of multiple blocks that will each represent a POJO instance (MyPojo.java)and storing these instances in a Collection. I also have a custom deserializer that will omit the creation of certain POJOs. At the minute I have the following in Jackson:
public Collection<MyPojo> load()
{
ObjectMapper mapper = new ObjectMapper().registerModule(new MyCustomDeserializer());
return mapper.readValue(jsonFile, new TypeReference<Collection<MyPojo>>(){});
}
I know that the Boon API mimics Jacksons so I tried:
ObjectMapper boonMapper = JsonFactory.create();
return boonMapper.readValue(jsonFile, new TypeReference<Collection<MyPojo>>(){});
...but it doesn't seem to like this, it can't find the method that accepts these types.
Forgetting the registering the custom deserializer for now (that'll be my next problem), is this type of deserialization, straight to a Collection, supported in Boon?
Do the following;
return boonMapper.readValue(jsonFile, List.class, MyPojo.class);

How to avoid any exceptions while converting a java object to JSON

I'm trying to generate a JSON string from a complex java object (using Jackson API). While parsing a field I see ClassCastException. The Java objects are not owned by my project so cannot change and fix the issue. Is there any easy way to fix this?
Please note, my code deals with any kind of Java object and doesn't this Java object in particular so I'm looking for something generic where if a field is not parsed successful, just ignore and move to the next one.
ObjectMapper mapper = new ObjectMapper();
CustomModule module = new CustomModule();
mapper.registerModule(module);
ObjectWriter ow = mapper.writer().withDefaultPrettyPrinter();
ow.writeValueAsString(value)
You can globally disable checking for instance :
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
By default Jackson throws an exception, if it encounters a JSON property that it can not bind to object property.

how does jackson derive type for deserialization in "Could not resolve type id 'foo' into a subtype

I'm trying to serialize/deserialize a group of objects including sub-classes with jackson. I am using the JsonTypeInfo and JsonSubTypes annotations. It works fine working with DynamoDB but I'm also trying to cache using Redis (via spring's redis components). It writes to redis fine, but am getting the following error when trying to retrieve from redis :
Could not resolve type id 'LinkedTreeMap' into a subtype of [simple type, myBaseClass] : known type ids = [myBaseClass, sub-class1, sub-class1...]
... through reference chain....->[collection of MyBaseClass]->java.util.ArrayList[0]...
I think the LinkedTreeMap is in the gson library. We have a pretty large maven project and gson is in there due to other library dependencies, but I don't see how or why it's being pulled into this usage. It looks like it's deriving this class based on the structure of the json. The Json it's trying to deserialize looks like it is a list instead of a map.
So where is this LinkedTreeMap coming from?
We are also using the following ObjectMapper for redis :
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(Include.NON_NULL);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.disable(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd\'T\'HH:mm:ss.SSSZ"));
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.registerModule(new JodaModule());
We are also using a custom serializer which implements RedisSerializer. You'd think this might be the first place to look for issues like this, but it is pretty minimal, and seems to be necessary when you autowire RedisTemplate with Spring #Bean.

Is there a JSON library that can serialize Proxy objects?

Using ActiveObjects as my ORM and Gson as my JSON processor.
Ran into a problem going toJson from
persisted objects. The problem is that my persisted class is actually
an Interface and AO is proxying that object under the hood. Here's
some sample code:
Venue venue = manager.get(Venue.class, id);
gson.toJson(venue);
Comes up with this exception:
java.lang.UnsupportedOperationException: Expecting parameterized type,
got interface java.lang.reflect.InvocationHandler.
Are you missing the use of TypeToken idiom?
See http://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and...
Because venue.getClass().getName() gives:
$Proxy228
I've tried a few solutions in various combinations:
gsonBuilder.registerTypeAdapter(Venue.class, newVenueSerializer());
Type listType = new TypeToken<Venue>() {}.getType();
Nothing has worked so far and I'm using a wonky field-by-field workaround. Any suggestions? I'm not married to Gson, so if there's an alternative library that can do this I'd be happy to use it.
Flex JSON should work - it will use the bean property introspector to pull the object, and I assume the proxy class implements those properly.
Also check out the Jackson.

Categories

Resources