I have an object similar to this:
public class Obj {
@XmlElement(name="value")
public Set<Object> values;
}
When marshaling, this is generating an xml like:
<Obj>
<value xsi:type="xs:dateTime" xmlns:xs="http://www.w3.org/2001/XMLSchema">2009-02-14T00:31:30.001+01:00</value>
<value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema">test</value>
</Obj>
However, I want to change some of that values (like the date format used for serializing Date
and Timestamp
objects), and also get rid of the annoying xsi
attributes (but this is not really a requirement, I can live with that)
I've tried adding a @XmlJavaTypeAdapter
to values
, but in the adapter I get the full Set<Object>
to adapt, instead of single elements. I've also tried with a package adapter, but, as my Set
is for Object
, I cannot put the @XmlJavaTypeAdapter(type)
attribute.
Also, I've tried with @XmlJavaTypeAdapter(value=MyAdapter.class, type=Timestamp.class)
to get only an adapter for the values inside that Object that I want.
So the question is, does someone know a way to get an adapter to work for this? Or maybe, change the date format every time a Date
or Timestamp
object is serialized?
Thanks in advance!
@XmlJavaTypeAdapter
with the type property has to be specified on the package level. When used in this way it indicates that all usages of that type within the specified package are converted using the XmlAdapter
. E.g. if you have a package-info.java
like
@XmlJavaTypeAdapters({
@XmlJavaTypeAdaptor(type=Timestamp.class, value=MyAdapter.class)
})
package org.example;
Then a class in that package with a Timestamp field.
package org.example;
public class Obj {
public Timestamp aTimestamp;
}
The specified adapter will be used to convert the timestamp. I suspect that this will work for your Set<Object>
case but I haven't tried it myself.
The reason for the xsi:type
attribute is that JAX-B likes to produce XML it can deserialize, so it needs to indicate what type it is or it could only parse everything back as strings. You can get rid of this attribute by using the @XmlElementRef annotation to create a schema substitution group, but in this case the XML will be produced with different element names. E.g.
public class Obj {
@XmlElementRefs({
@XmlElementRef(type=String.class, name="string"),
@XmlElementRef(type=Timestamp.class, name="timestamp")
})
public Set<Object> value;
}
Would produce the following XML structure if you had a timestamp and a string in the set. In this scenario the xsi:type
attribute is unnecessary since JAX-B can tell what type to create from the element name.
<Obj>
<timestamp>2009-02-14T00:31:30.001+01:00</timestamp>
<string>test</string>
</Obj>
I would strongly recommend using the @XmlElementWrapper annotation to wrap up all the set items if you're going to take this approach.
If all you're after is a simple set of strings that you don't care about deserializing back to Java (or any other) objects with the correct types, then the simplest solution is to have an XmlAdapter that does just adapt the full Set<Object>
into a Set<String>
and handle the conversion yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With