The goal is to produce the following XML with JAXB
string data
binary data
>
You could leverage an XmlAdapter
for this use case instead of @XmlValue
:
BarAdapter
package forum8807296;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class BarAdapter extends XmlAdapter
Foo
The XmlAdapter
is associated with the bars
property using the @XmlJavaTypeAdapter
annotation:
package forum8807296;
import java.util.List;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Foo {
private List bars;
@XmlElement(name="bar")
@XmlJavaTypeAdapter(BarAdapter.class)
public List getBars() {
return bars;
}
public void setBars(List bars) {
this.bars = bars;
}
}
Bar
package forum8807296;
public class Bar {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
Demo
You can test this example using the following demo code:
package forum8807296;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class);
Foo foo = new Foo();
List bars = new ArrayList();
foo.setBars(bars);
Bar stringBar = new Bar();
stringBar.setValue("string data");
bars.add(stringBar);
Bar binaryBar = new Bar();
binaryBar.setValue("binary data".getBytes());
bars.add(binaryBar);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(foo, System.out);
}
}
Output
Note how the output includes the xsi:type
attributes to preserve the type of the value. You can eliminate the the xsi:type
attribute by having your XmlAdapter
return String
instead of Object
, if you do this you will need handle the conversion from String
to the appropriate type yourself for the unmarshal operation:
string data
YmluYXJ5IGRhdGE=