Custom Serialization in JAXB

Is there a way to set up XML serialization in JAXB, just as it is possible with IXmlSerializable in .NET? (i.e. the ability to directly control the serialization of an object using the equivalent of XmlReader / Writer).

I took a look at the XmlAdapter and @XmlJavaTypeAdapter, but they are just used to convert types to and from serializable forms, which is not exactly what I want.

Update. In particular, I would like to configure the deserialization of the root object, which programmatically determines how to deserialize the internal XML (for example, create an unmarshaller jaxb with a specific set of known types).

Update: I found a way to solve the problem, but it is such an unpleasant hack, I will probably go with one of the solutions suggested by the other posters.

0
source share
3 answers

I'm not sure I fully understand what your goal is, but perhaps you could do what you want to do programmatically inside the no-args constructor of your root object, which will be called to instantiate the object when it is not unarmed.

+1
source

, , , , , , . , , Java JAXB , XML.

. ...

// Create an instance of this class, to wrap up whatever you want to custom-serialize
@XmlRootElement
public static class SRef
{
    public SRef() { }
    public SRef(Object ref)
    {
        this.ref = ref;
    }

    @XmlJavaTypeAdapter(SRefAdapter.class)
    public Object ref;
}

// This is the adapted class that is actually serialized 
public static class SRefData
{
    // This is a hint field to inform the adapter how to deserialize the xmlData
    @XmlAttribute
    public String hint;

    // This contains the custom-serialized object
    @XmlElement
    public String xmlData;
}

    // Converts an object to and from XML using a custom serialization routine
public static class SRefAdapter extends XmlAdapter<SRefData, Object>
{
    @Override
    public SRefData marshal(Object value) throws Exception
    {
        if (value instanceof MyType)
        {
            SRefData data = new SRefData();
            data.xmlData = doSomeSpecificSerialization(value);
            data.hint = "myType";
            return data;
        }
        throw new IllegalArgumentException("Can't serialize unknown object type " + value.getClass());
    }

    @Override
    public Object unmarshal(SRefData refData) throws Exception
    {
        if (refData.hint.equals("myType"))
        {
            return doSomeSpecificDeserialization(refData.xmlData);
        }
        throw new IllegalArgumentException("Unhandled hint value in SRefData: " + refData.hint); 
    }
}
+3

, , root node / xml - , node.

JAXB, (xsd), Java, . . , JAXB , , , , . ...

Consider this: http://www.w3schools.com/Schema/schema_complex_indicators.asp

Instead of switching unmarshaller, just include both xml definitions. They will be analyzed independently, and you can change the control flow of the program through any attribute that you would check on the root folder of the node.

+1
source

Source: https://habr.com/ru/post/1736466/


All Articles