Jackson JSON : top level segment inclusion - json

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.

Related

How to apply low-level character filter to Jackson JSON parsing?

I have a (JSON) REST-based application based on Spring and RESTEasy. We have a requirement to limit the set of characters that are accepted as input to the services. I could apply the restriction to the POJOs themselves during or after deserialization, but it seems more efficient to insert some kind of filter into the Jackson parsing as it's reading the JSON stream, since it's obviously inspecting each character at some point anyway.
Question is, does Jackson provide a plug-in point to do that? Something that would enable me to decorate or override the low-level parsing at such a time that I could verify each character of each property value is valid (i.e., in a particular set according to the app requirements).
If you mean allowed characters within JSON String values, no, there is no filter or transformer functionality currently. You could consider implementing JsonParserDelegate, which could intercept calls to getText(), but that may not be very clean mechanism. Alternatively you could first read content as tree (JsonNode), traverse it and cleanse String values; and only after that do data-binding using ObjectMapper.convertValue(fromNode, MyType.class).
In the context of RESTEasy, you can inject the custom JsonParserDelegate by extending MappingJsonFactory and overriding the _createJsonParser(...) methods to return the custom delegate. Then implement an extension to JacksonJsonProvider (Jackson's JAX-RS provider) that creates an ObjectMapper with your custom factory in its constructor. Examples of this can be found in this answer to a related question.

Jackson JSON provider for cxf:rsServer

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.

Unable to use "as JSON" after upgrading to grails 2.1.1 from grails 1.3.4

I'm in the process of upgrading a grails plugin from 1.3.4 to grails 2.1.1. After upgrading I now have an integration test that fails that was not failing before. It fails on using the "as JSON" (grails.converters.JSON).
#Test
public void testConvertCollectionOfEnvironmentSettingsToJSON() {
EnvironmentSetting setting = configurationService.getEnvironmentSetting('ENFORCE_SCHEMA_INSTANCE_RULE')
def jsonSetting = setting as JSON //exception thrown here
def s = jsonSetting as String
assertNotNull jsonSetting
}
The exception and stacktrace:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'com.company.ipsvc.configuration.domain.EnvironmentSettingAllRevs#48c12420' with class 'com.company.ipsvc.configuration.domain.EnvironmentSettingAllRevs' to class 'grails.converters.JSON'
at com.company.ipsvc.configuration.converter.json.basic.BasicEnvironmentSettingJSONIntegrationTests.testConvertCollectionOfEnvironmentSettingsToJSON(BasicEnvironmentSettingJSONIntegrationTests.groovy:28)
I am able to use encodeAsJSON() successfully. I also have the same issue with as XML.
I think converters (as JSON syntax) will only work on domain objects and collections by default.
To convert arbitrary objects you should use the encodeAsJSON() converter, I believe. Or use an object marshaller, where you tell the converter how to deal with your object.
The docs aren't very clear on this though..
See:
http://grails.org/Converters+Reference (object marshalling section at bottom)
http://grails.org/doc/latest/ref/Plug-ins/codecs.html
But I note that http://grails.org/doc/latest/api/grails/converters/JSON.html#JSON%28java.lang.Object%29 says that the object converts POGOs.. Maybe it means if you have a marshaller?
I did find this reference too:
Notice that the ‘as’ operator is not overloaded for plain objects ...
Domain objects can use the ‘as’ operator to cast an object to JSON, the same as a collection. So unlike POGOs, where they must be massaged into a list or have encodeAsJSON explictly called ...
http://manbuildswebsite.com/2010/02/08/rendering-json-in-grails-part-2-plain-old-groovy-objects-and-domain-objects/
Which seems to describe the situation.
For non-Domain objects, we found that this would crop up when running tests... the solution for us was to use new JSON:
render new JSON( obj )
This would allow the test to work, and the code does the same thing (essentially)
Ran into a similar issue that broke unit test using grails 2.2.1 . At issue was a straight obj as JSON conversion attempt. But this was interpreted as type casting instead.
The workaround is to stuff your obj to be converted into a map like this [data:obj] as JSON

Jackson JSON library how to disable serialization of a given type

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?

JAXB A cycle is detected in the object graph

I want to convert my pojo to json with JAXB, my pojo have one to many relation, and when i convert my pojo to json, JAXB generate error "A cycle is detected in the object graph. This will cause infinitely deep XML".
I read from web that, this problem can be solved with help from #XmlID and #XmlIDREF, but there is one problem, my Id attribute is not String type but Long. and as far as i know #XmlID can be used only with String property.
Other web suggest using eclipselink MOXy, but MOXy cannot generate json.
As you mentioned in your question EclipseLink MOXy (I'm the tech lead) has the #XmlInverseReference annotation to solve the problem of bidirectional relationships. As of EclipseLink 2.4 MOXy can produce/consume JSON.
For More Information
http://bdoughan.blogspot.com/2010/07/jpa-entities-to-xml-bidirectional.html
http://blog.bdoughan.com/2011/08/json-binding-with-eclipselink-moxy.html
You have a cyclic reference problem in your definition.
Try putting #XmlTransient above the problematic definition.
Also, about XmlID and string type, see http://markmail.org/message/up6vrzjixxrvy5th.
The JAXB specification requires that the property marked with #XmlID be a String property.
MOXy impl allows to use long.
One hack to keep using full JAXB compliant implementation would be to duplicate your id in a String field (before serialising)
Don't know so much about JAXB but XStream makes you able to use different modes and some of these modes will give references to the xpath address (absolute or relative) of an element in your xml, if these elements are already displayed.
(And you can do Json with XStream)
I faced similar problem when I wanted to convert my POJO to JSON with JaxRS. The MoxyJsonProvider is the default option of eclipselink but it fails to parse the JSOG (where cycles exists in the JSON structure). Jackson Jaxb Provider does this better with ObjectMapper.
I have elaborated in this answer below, about how to invoke Jackson Provider instead of Moxy. You will need jackson packages in your pom xml.
https://stackoverflow.com/a/60319306/5076414