0

I have a simple class which must be marshalled/unmarshalled with a specific XmlAdapter:

package jaxb;

import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Arrays;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.xml.sax.InputSource;

@XmlRootElement(name = "simpleClass")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapter(MyAdapter.class)
public class SimpleClass implements Serializable {

    private static final long serialVersionUID = 1L;

    public byte[] bytes;

    /**
     * Return bytes value or reference.
     *
     * @return bytes value or reference.
     */
    public byte[] getBytes() {
        return bytes;
    }

    /**
     * Set bytes value or reference.
     *
     * @param bytes Value to set.
     */
    public void setBytes(byte[] bytes) {
        this.bytes = bytes;
    }

    public static void main(String[] args) {

        try {

            JAXBContext context = JAXBContextFactory.createContext(new Class[] {
                    SimpleClass.class
            }, null);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            Marshaller marshaller = context.createMarshaller();

            StringWriter sw = new StringWriter();
            StringReader sr = new StringReader("<simpleClass><bytes>DT8d6/Y8/Ig=</bytes></simpleClass>");

            SimpleClass binaryData = (SimpleClass) unmarshaller.unmarshal(new InputSource(sr));
            System.out.println("Unmarshal is: " + binaryData + "");
            System.out.println("Binary data bytes: " + Arrays.toString(binaryData.bytes) + " ");

            marshaller.marshal(binaryData, sw);
            System.out.println("Marshal is: " + sw.toString() + "");

        }

        catch (Throwable e) {

            e.printStackTrace();
        } finally {

        }
    }
}

My adapter is the following:

package jaxb;

public class MyAdapter extends XmlAdapter<String, Object> {

    @Override
    public String marshal(Object arg0) throws Exception {

        ...
    }

    @Override
    public Object unmarshal(String arg0) throws Exception {
        ...
    }
}

I think that this is enough to tell to JAXB engine to use the provided adapter class to marshal/unmarshal SimpleClass objects. It looks like the adapter is not invoked on @XmlRootElement objects, but only on fields of it. In fact, if I use the XmlJavaTypeAdapter annotation on the "bytes" field, for example, the adapter is invoked.

Any help will be appreciated.

Evgenij Reznik
  • 17,916
  • 39
  • 104
  • 181
Lazarus
  • 147
  • 13
  • Thats not really how typeadapter work. Why do you want the type adapter on the `@XmlRootElement`? – k5_ Dec 13 '19 at 18:30
  • Because i would like to use a generic adapter for all fhe elements in my object, and apply some kind of logic inside my adapter. – Lazarus Dec 13 '19 at 18:36

0 Answers0