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.
Related
When I use an ObjectMapper configured as:
DefaultTyping applicability = ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT;
TypeResolverBuilder<?> typer = DefaultTypeResolverBuilder.construct(applicability, validator);
String propertyName = "type";
typer = typer.init(JsonTypeInfo.Id.NAME, null);
typer = typer.inclusion(JsonTypeInfo.As.PROPERTY);
typer = typer.typeProperty(propertyName);
ObjectMapper mapper=new ObjectMapper();
mapper.setDefaultTyping(typer);
It produces JSON like:
{
"type": "ShortClassName",
...
}
The type does not have the full package name as expected. However trying to deserialize using this object mapper cause:
com.fasterxml.jackson.databind.exc.InvalidTypeIdException
How do I specify the base package name as part of the object mapper configuration so that the serialized JSON only has the classname?
You can create a mapper for a specific Object by using mapper.readerFor(...) and specifying which type to extract, in this case this would be
ObjectReader shortClassNameReader = mapper.readerFor(new TypeReference<ShortClassName>(){})
Where ShortClassName is your class's name.
Then you can use this ObjectReader with readValue to deserialize the JSON.
Thanks Ayk - your solution works if the class name is itself the one to be deserialized but if it is nested inside the JSON for another class, it does not work. However I got it working by defining a custom typeIdResolver that translates the ID from/to object in idFromValue and typeFromId respectively. This then works globally without the need for annotation on each object involved in the serialization.
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.
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);
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>.
I've started using Jackson as a JSON generator, as an alternative to google GSON. I've run into an issue where Jackson is generating object: null if the object is indeed null. GSON on the other hand generates NO entry in JSON, which is the behavior I want. Is there a way to stop Jackson from generating null object/value when an object is missing?
Jackson
ObjectMapper mapper = new ObjectMapper();
StringWriter sw = new StringWriter();
mapper.writeValue(sw, some_complex_object);
String jackson = sw.getBuffer().toString();
System.out.println("********************* START JACKSON JSON ****************************");
System.out.println(jackson);
System.out.println("********************* END JACKSON JSON ****************************");
generates this:
{"eatwithrustyspoon":{"urlList":null,"device":"iPad","os":"iPhone OS","peer_id":
and GSON looks like this:
Gson gson = new Gson();
String json = gson.toJson(some_complex_object);
System.out.println("********************* START GSON JSON ****************************");
System.out.println(json);
System.out.println("********************* END GSON JSON ****************************");
and it generates this (which is what I want - note that "urlList":null was not generated) :
{"eatwithrustyspoon":{"device":"iPad","os":"iPhone OS","peer_id"
From the Jackson FAQ:
Can I omit writing of Bean properties with null value? ("how to prevent writing of null properties", "how to suppress null values")
Yes. As per JacksonAnnotationSerializeNulls, you can use:
objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
// or (for older versions):
objectMapper.configure(SerializationConfig.WRITE_NULL_PROPERTIES, false);
and voila, no more null values. Note that you MUST configure mapper before beans are serialized, since this setting may be cached along with serializers. So setting it too late might prevent change from taking effect.
my issue was bit different actually i was getting Null values for the properties of POJO class.
however i solved the problem by giving mapping to properties in my pojo class like this :
#JsonProperty("PROPERTY_NAME")
thought it may help someone :)
The following solution saved me.
objectMapper.setSerializationInclusion(Include.NON_NULL);