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:dateTime
t开发者_如何转开发o 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
精彩评论