customized property name using jaxb annotations - java

I have a pojo definition like following:
class Pojo<T>
{
private T entity;
//setters and getters;
}
I want to serialize this pojo into json using jackson and jaxb annotations. I want the property name in json to be the type of T not the name "entity". I tried few things with jaxb annotations but nothing worked as expected.
Any help would be much appreciated.

Related

Convert XML to JSON with different property names using Jackson

I have the next task: read XML file from some directory and convert it to JSON string.
The problem: initial XML and JSON have different names for corresponding properties, e.g. x_date in XML and j_date in JSON.
I have created the class with required field for JSON with such annotations:
public class Card {
#JacksonXmlProperty(localName = "x_date")
#JsonProperty("j_date")
private String date;
// other fields
I have tried to serialize/deserialize test XML file, and it's seems work correctly.
But I'm not sure that is ok to annotate fields with #JacksonXmlProperty and #JsonProperty annotations at the same time. Maybe it's better to create one class per XML part and one for the JSON and transfer the data between them some mapper (e.g. Orika)?
Any suggestions?
Finally solved this by splitting logic in two separate classes: Card.class for XML data with help of #JacksonXmlProperty annotation and CardDto.class which uses #JsonProperty. Mapping between these classes is handled by Orika mapper.
This split will ease further customization of both classes and will allow add new functionality (e.g. persist data to the database using new entity class).

How do I get Jersey to show a List in an object persisted by Hibernate?

Jersey is not showing a list in the JSON output when I retrieve the object using Hibernate. The list within the object is defined like this:
#OneToMany(cascade=CascadeType.ALL)
#OrderColumn
private List<Project> projects = new ArrayList<Project>();
When I retrieve the object (which also contains the projects list), I get the normal fields (ints and Strings and such), but not this list. When I use the debugger, I can see that the list is indeed there, but Jersey doesn't output it in JSON.
It looks like you need to configure a JSON Serializer such as Jackson. The answers to this question have some guidance on how to do that.
Once you have Jackson with JAXB support configured, you will need to add appropriate JAXB annotations to the Project class (either XML based one or JSON based ones, the serializer can be configured to support either or both). So, for example adding this to Project
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "")
#XmlRootElement(name = "project"))
public class Project {
Should be enough to serialize Project and it's fields to JSON.

JsonIgnore & XmlElement annotations conflict

I've faced issue to combine JAXB and Jackson annotation together:
public class Document {
String someField;
#JsonIgnore
#XmlElementWrapper(name = "someWrapper")
#XmlElement(name = "someElement")
List<String> someCollection;
}
I need to be able to marshall and unmarshall field 'someCollection' to xml, but to have the opportunity to serialize 'Document' object to json without such field.
But this field appears in final json string
So, if I've understood right - Jackson sees both JsSON and XML annotations. So I can not force to serialize something and do not serialize in the same moment.
It is not possible, I think

Which attribute in XSD will annotate a field with #XmlElement(required = false) in JAXB generated classes

I want to annotate a field in my jaxb generated class with this annotation - #XmlElement(required = false). Which attribute in the XSD would generate my field with this annotation?.
I can't hand type this as the JAXB classes are auto generated using Maven every time a build is run.
My jaxb version is xjc 2.2.4-2
Thanks
When an element has minOccurs="0" the corresponding #XmlElement has required=false. Note that false is the default value of the required attribute so it may not actually appear in the generated annotation.
UPDATE
Based on your comment:
Let me explain my actual problem. I'm using Jackson to generate the
JSON from the JAXB classes. Issue is when the element is not
present in the xml, I see the json output with the field name as 'pip'
and value as null. I am actually expecting the field 'pip' to be
absent from my json output as I declared it to be minOccurs=0 in the
XSD. Can't figure out if it's an issue with JAXB or Jackson.
Interestingly when I annotate the field explicitly with required=false
in the jaxb class, I see my expected output with the field being
absent
This is an issue with Jackson not handling the default value of the required property on the #XmlElement annotation correctly.

Tell JAXB to unmarshal <xs:dateTime> to Date class using annotations

When using JAXB with Java-First, fields/properties of type java.util.Date are marshalled and unmarshalled as xs:dateTime and everything works as expected.
But if the type of the field/property is Object, JAXB unmarshals xs:dateTimeto XMLGregorianCalendarImpl.
I need to find a way that makes JAXB unmarshal date-time values to java.util.Date by itself using annotations. Otherwise, I'll need to go through all unmarshalled values in each use case.
Even if there were some after-unmarshall-hook to define on the classes containing Object fields and convert the instances manually would be good. But I couldn't find anything that can be used this way either.
Note that I have limited access to the JAXB context, as it is used inside Apache CXF.
In addition to Blaise Doughan's answer:
I could finally figure this out, thanks for help from Blaise Doughan. Actually his answer works with just a small change: if there's several types expected to be unmarshalled as the Object property, there needs to be multiple #XmlElement annotations placed on it using #XmlElements annotation.
Here's my code now:
#XmlElements
({
#XmlElement(name = "dateValue", type = Date.class),
#XmlElement(name = "stringValue", type = String.class),
#XmlElement(name = "booleanValue", type = Boolean.class),
#XmlElement(name = "listValue", type = ArrayList.class),
#XmlElement(name = "bytesValue", type = Byte[].class)
})
public Object getFieldValue()
{
return fieldValue;
}
Note: specifying "name" is required for this to work, since there should be a way for the marshaller / unmarshaller to identify the type of the content.
There are two minor issues here:
You need to specify a list of all of the types expected (which is logical, given the case of marshalling)
There's no way to specify a single name for this property. In my case, where JAXB is used in CXF web services, code generated from WSDL in .NET names this field as "Item". If there was a way, for example, to wrap the XML elements in another one which has a single name, the generated code could be a little bit nicer.
You can set the type property on #XmlElement.
#XmlElement(type=Date.class)
public Object getGenericDateProperty() {
return date;
}
Edit:
Since you don't know the type you could use an XmlAdapter. If the unmarshalled value is an XMLGregorianCalendar convert it to a Date. For more info on XmlAdapter see:
http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html

Categories