I understand that I can control the behavior of Jackson's ObjectMapper to include information about the identity of objects using the #JsonIdentityInfo annotation on a class.
Is it possible to achieve this by configuring the ObjectMapper itself to include type identity information for every object?
Is there a reason why the ObjectMapper should not be configured in this way (i.e. if there is no way to do this, is there a good reason for that)?
Related
I'm implementing a REST service using Camel's cxfrs component. Various examples I've seen around the inets say I can get the service to return a JSON serialization of the object in question using a cxf:providers tag, like so
<cxf:rsServer id="rsServer" address="${CXFserver}${service}" serviceClass="org.trinityhealth.esb.PersonService"
loggingFeatureEnabled="true" loggingSizeLimit="20">
<cxf:providers>
<bean id="jsonHandler" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
</cxf:providers>
</cxf:rsServer>
This compiles and deploys just fine. But no matter what variant of this config I try, the service responds with "No message body writer has been found for response class Person". The Person class has a "#XmlRootElement(name = "Person")" annotation in it, which I guess is great if I wanted XML produced. But I don't - I want JSON. Jackson has a ton of annotations, do I need to add one to the Person class to get my service to realize I want the class serialized by the Jackson writer?
I don't know Camel that well, but typically Jackson does NOT require root annotation, unlike JAXB (partly since JSON structure does not require name for root type), so it seems unlikely you would such annotation.
I am guessing that rather the registration does not succeed for some reason.
I need my Grails app to communicate (JSON) with client that uses Jackson. By default Grails include 'class' in the generated json. On the other hand, default Jackson's ObjectMapper doesn't recognize 'class', it throws error.
I've found solution, by adding #JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="class") on each POJO classes that are being used.
But, I don't prefer that approach. Because now my POJO will have dependency to Jackson's jar. Is there another easy alternative?
I was trying to figure out from objectMapper.getSerializationConfig(). ..., but still couldn't found the alternative to replace that annotation.
Thanks
Are you using the type info for polymorphic instantiation or are you ignoring that information? You could probably use instead #JsonIgnoreProperties({"class"}) on your classes.
If you really don't want to add annotation to your classes, you can use the mix-in mechanism. Although it is much more easier to add the annotation directly to your classes, if you control the classes of course.
mapper.addMixInAnnotations(YourClass.class, TypeInfoMixIn.class);
mapper.addMixInAnnotations(YourSecondClass.class, TypeInfoMixIn.class);
// etc.
#JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="class")
public class TypeInfoMixIn {}
I need to generate Json from the domain object. I can't add annotation in the domain classes.
Using Mixin is not a option because I have to ignore a lot of properties.
My approach was create a DTO object with the properties that I need. And populate the dto using dozer and then generate Json from the dto with jackson. It looks too much.
I would like to know if is posible to configure Jackson from xml, in order to generate json with the properties mapped in the xml, so it would not be necessary to use dto and dozer.
No. Jackson does not support external configuration files.
But you don't explain how or why you would use Dozer, or DTO. Why not just add properties you care about in a Map, and serialize that as JSON? Then you can use whatever mechanism you want to build/trim that Map.
Jackson can also convert values, so to create full Map with everything from another object, you can do:
Map<String,Object> map = objectMapper.convertValue(someBean, Map.class);
and maybe then only retain properties you want.
I am using JACKSON 1.6.3 version. I have one class which has a reference to itself and JACKSON serializer is failing with complains about "circular references".
I would like to disable serialization of this class. This is a third party class and I can not add any annotation to it, I am wondering if there is a way to disable this type of object being serialized. I am ok if the serializer ignores the entire object.
I fixed the issue by creating a custom JsonSerializer<T> for the type and registered it with ObjectMapper
mapper = new ObjectMapper();
CustomSerializerFactory factory = new CustomSerializerFactory();
factory.addSpecificMapping(<Type to be handled>, <Custom Serializer>);
mapper.setSerializerFactory(factory);
This can also be done using JacksonMixInAnnotations.
See the accepted answer on How can I tell jackson to ignore a property for which I don't have control over the source code?
I am referring to this post: convert json to object using jackson , and the last answer there by StaxMan, which says it's possible in Jackson 1.7 to set the configuration such that Jackson starts producing (and maybe parsing too?) the top-level tag/segment in the JSON.
Can someone shed some light on how to set that configuration, and it is only for JSON generation or parsing as well?
Thank you very much!
You need to create and configure the ObjectMapper with the WRAP_ROOT_VALUE feature, e.g.
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
See javadoc:
Feature that can be enabled to make root value (usually JSON Object but can be any type) wrapped within a single property JSON object, where key as the "root name", as determined by annotation introspector (esp. for JAXB that uses #XmlRootElement.name) or fallback (non-qualified class name). Feature is mostly intended for JAXB compatibility.
Default setting is false, meaning root value is not wrapped.
The javadoc also says that it hasn't yet been implemented, but I can see it being used in the Jackson source, so it might work OK. I haven't actually tried it myself, though.