Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB (un)marshalling of xsd types: xsd:base64Binary and xsd:hexBinary

JAXB maps both xsd:base64Binary and xsd:hexBinary types to byte[].

Given that I have a schema/a DOM Element representing each of these types such as:

<foo>ABCD</foo> for xsd:hexBinary and
<foo>YTM0NZomIzI2OTsmIzM0NTueYQ==</foo> for xsd:base64Binary ,

it's not clear how JAXB 2.1 handles it.

JAXB.unmarshal(new DOMSource(node), byte[].class) does not like the payload.
Neither does the following:

JAXBContext ctx = JAXBContext.newInstance(byte[].class); ctx.createUnmarshaller().unmarshal(node);

What's the correct way of handling these types? Thanks in advance.

like image 711
Anand Avatar asked Nov 17 '10 06:11

Anand


People also ask

What is JAXB marshalling and Unmarshalling?

JAXB definitionsMarshalling is the process of transforming Java objects into XML documents. Unmarshalling is the process of reading XML documents into Java objects. The JAXBContext class provides the client's entry point to the JAXB API. It provides API for marshalling, unmarshalling and validating.

What is the use of XSD file in Java?

xsd is the XML schema you will use as input to the JAXB binding compiler, and from which schema-derived JAXB Java classes will be generated.


1 Answers

The conversion between byte[] and the hexBinary or base64Binary representation is done via a correspondent XmlAdapter.

by default JAXB uses the included HexBinaryAdapter for converting byte[] to a String. I don't know if there is also an XmlAdapter which converts from/to base64 but that is no problem:

You can easily implement it yourself using an own XmlAdpater:

public final class Base64Adapter extends XmlAdapter<String, byte[]> {
    public byte[] unmarshal(String s) {
        if (s == null)
            return null;
        return org.apache.commons.codec.binary.Base64.decodeBase64(s);
    }

    public String marshal(byte[] bytes) {
        if (bytes == null)
            return null;
        return org.apache.commons.codec.binary.Base64.encodeBase64String(bytes);
    }
}

You can specify on a field/getter_setter level what should be processed by which adapter:

private class DataTestClass {

    @XmlJavaTypeAdapter(Base64Adapter.class)
    public byte[] base64Data = new byte[] { 0, 1, 2, 3, 4 };

    @XmlJavaTypeAdapter(HexBinaryAdapter.class)
    public byte[] hexbinData = new byte[] { 0, 1, 2, 3, 4 };

}
like image 160
Robert Avatar answered Nov 28 '22 04:11

Robert