Java HTML / XML How to - Use JAXB generic @XmlValue








Question

We would like to know how to use JAXB generic @XmlValue.

Answer

import java.util.ArrayList;
import java.util.List;
//w  w w.j av  a  2  s .  c  o m
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

public class Main {

  public static void main(String[] args) throws Exception {
    JAXBContext jc = JAXBContext.newInstance(Foo.class);

    Foo foo = new Foo();
    List<Bar> bars = new ArrayList<Bar>();
    foo.setBars(bars);

    Bar<String> stringBar = new Bar<String>();
    stringBar.setValue("string data");
    bars.add(stringBar);

    Bar<byte[]> binaryBar = new Bar<byte[]>();
    binaryBar.setValue("binary data".getBytes());
    bars.add(binaryBar);

    Marshaller marshaller = jc.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    marshaller.marshal(foo, System.out);
  }

  public static class BarAdapter extends XmlAdapter<Object, Bar<?>> {

    @Override
    public Bar<?> unmarshal(Object v) throws Exception {
      if (null == v) {
        return null;
      }
      Bar<Object> bar = new Bar<Object>();
      bar.setValue(v);
      return bar;
    }

    @Override
    public Object marshal(Bar<?> v) throws Exception {
      if (null == v) {
        return null;
      }
      return v.getValue();
    }

  }

  @XmlRootElement
  public static class Foo {
    private List<Bar> bars;

    @XmlElement(name = "bar")
    @XmlJavaTypeAdapter(BarAdapter.class)
    public List<Bar> getBars() {
      return bars;
    }

    public void setBars(List<Bar> bars) {
      this.bars = bars;
    }

  }

  public static class Bar<T> {
    private T value;

    public T getValue() {
      return value;
    }

    public void setValue(T value) {
      this.value = value;
    }
  }
}