Daniel
Daniel

Reputation: 422

JAX-RS + JAXB (XML) -- How to pass single byte as hexadecimal?

To pass a byte array as hexadecimal we can use:

@XmlElement
@XmlJavaTypeAdapter(HexBinaryAdapter.class)
private byte[] data;

How can we transfer a single byte formatted as hexadecimal? With the following code it does not work. When I try to read it like this I get: HTTP Status 500 - Internal Server Error.

@XmlAttribute
@XmlJavaTypeAdapter(HexBinaryAdapter.class)
private byte id;

Upvotes: 1

Views: 1736

Answers (1)

bdoughan
bdoughan

Reputation: 149037

You could do the following:

XmlAdapter (ByteAdapter)

You could create your own XmlAdapter that converts between a Byte and the desired hexBinary String.

import javax.xml.bind.DatatypeConverter;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class ByteAdapter extends XmlAdapter<String, Byte> {

    @Override
    public Byte unmarshal(String v) throws Exception {
        return DatatypeConverter.parseHexBinary(v)[0];
    }

    @Override
    public String marshal(Byte v) throws Exception {
        return DatatypeConverter.printHexBinary(new byte[] {v});
    }

}

Domain Model

For the XmlAdapter to work across all JAXB (JSR-222) implementations it will need to be placed on a field/property of type Byte and not byte. In this example we will make the field Byte and leverage field access with JAXB keeping the property of type byte. We will leverage the @XmlSchemaType annotation to specify that the corresponding schema type is hexBinary.

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

    @XmlJavaTypeAdapter(ByteAdapter.class)
    @XmlSchemaType(name="hexBinary")
    public Byte bar;

    public byte getBar() {
        return bar;
    }

    public void setBar(byte bar) {
        this.bar = bar;
    }

}

Demo

Below is some code you can run to prove that everything works.

import java.io.File;
import javax.xml.bind.*;

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum17483278/input.xml");
        Foo foo = (Foo) unmarshaller.unmarshal(xml);

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

}

input.xml/Output

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <bar>2B</bar>
</foo>

Upvotes: 1

Related Questions