Can @JsonTypeInfo be used with collections?

Using Spring 3 and Jackson 1.7.6, I can serialize implementations of an abstract class and print the fully qualified class name as a property called @class . This works fine when my Spring controllers return a single instance from a controller annotated with @ResponseBody .

When the Collection above types is returned, the resulting JSON changes depending on what type is being serialized (fields from each subclass are present), but it does not include the @class property, which is required by our client code.

How can I get a hint of this type in serialized JSON when returning a collection?

 //Returns complete with @class=com.package.blah @RequestMapping("/json/getProduct.json") public @ResponseBody Product getProduct(Integer id) { return service.getProduct(id); } //Does not include @class @RequestMapping("/json/getProducts.json") public @ResponseBody List<Product> getProducts() { return service.getProducts(); } 
+4
source share
3 answers

To do this, you will need to configure ObjectMapper. This is not just using Spring, but instead of settable properties, ObjectMapper has invokable methods that set its state (and then it saves it as a bitmask).

If you use <mvc:annotation-driven /> , you will need to replace it with equivalent markup, which can be found in Spring JavaDocs.

Extend ObjectMapper:

 public class ConfigurableObjectMapper extends ObjectMapper { public ConfigurableObjectMapper() { this.enableDefaultTypingAsProperty(DefaultTyping.JAVA_LANG_OBJECT, JsonTypeInfo.Id.CLASS.getDefaultPropertyName()); } } 

Then tell Spring to use an instance of this class instead of the default implementation.

 <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="order" value="0" /> </bean> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="webBindingInitializer"> <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <property name="validator" ref="validator" /> </bean> </property> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="objectMapper"> <bean class="com.blitzgamesstudios.web.common.json.ConfigurableObjectMapper" /> </property> </bean> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" /> <bean class="org.springframework.http.converter.StringHttpMessageConverter" /> <bean class="org.springframework.http.converter.FormHttpMessageConverter" /> <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" /> </list> </property> </bean> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /> 
+2
source

You can use @JsonTypeInfo with POJOs, collections, and maps, but note that the type of declared collection and map types must be one that has (or inherits) the @JsonTypeInfo annotation (when using the @ -sonTypeInfo annotation for each class). This will not work, for example, if you have a type of type "Collection" - in this case, Deejay's answer is correct, since you can force the "default" parameter to be enabled.

But everything should work if you have a Collection property for serialization / deserialization, that is:

 public class Bean { @JsonTypeInfo(....) public Collection<Object> listOfObjects; // does work because it per-property annotation! // ... also, applies to value type and not Collection type itself } 

as this will override any type of @JsonTypeInfo annotation value, otherwise

+2
source

I had a problem with java.util.Map , so I did something like:

public interface MyMap extends Map<Long, Product> {}

and

public class MyHashMap extends HashMap<Long, Product> implements MyMap {}

Found at: http://jackson-users.ning.com/forum/topics/mapper-not-include-type-information-when-serializing-object-why

0
source

All Articles