JAXB A cycle is detected in the object graph - json

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

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.

Parsing Jackson annotations with Swagger

By default, Swagger parses a class's data members in order to document the objects used as parameters or returned by a given web service. If you're using Jackson, the Jackson annotations provide a much more accurate description of the API.
Does anyone know an (easy) way to get Swagger to parse Jackson annotations. Perhaps an overridden parser?
Not sure if this would help, but Jackson 2.1 and later expose POJO structure as seen by Jackson itself (ObjectMapper.acceptJsonFormatVisitor), which could be used for generating different kinds of artifacts. I have written an Avro schema generator with it, for example (as part of Jackson Avro module)
As of version 1.2, Swagger can parse Jackson annotations on its own. I confirmed this using Jackson 2.1.

Jackson JSON : top level segment inclusion

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.

Jackson serialise fields as uppercase?

My object gets serialised as {name="nyname" ....}, however, I require all keys to be start with uppercase, ie. {Name="myname",.....} how can I do that with Jackson ?
I had the same issue and posted about it earlier. I solved it here:
How can I enable Pascal casing by default when using Jackson JSON in Spring MVC?
If you're not using Spring, the answer would be similar. You'll still need a custom (de)serializer, and you'd just need to wire it in to your program in the manner you choose.