Using an adapter to marshal a class to a root element with MOXy or any other JAXB implementation

狂风中的少年 提交于 2019-12-01 05:34:16

问题


I have a class which extends the CompositeConfiguration class from Apache Commons Configuration. I am trying to marshal it to XML using MOXy. I have created an XML adapter that converts the configuration to a list of simple name/value objects.

I have tried using a number of variations on what I have below but am still stymied. I can see my adapter class being loaded and instantiated when I create the JAXB context but it is never called when I marshal the configuration object.

Looking at the MOXy source code, I am beginning to suspect that it is impossible to specify an XML adapter for a Java class that is also a root element. Am I on the right track to getting this working or is there a completely different way to do this?

XML adapter:

public class JAXBConfigurationAdapter extends XmlAdapter<Object, BetterBaseConfiguration>
{

    @Override
    public Object marshal(final BetterBaseConfiguration javaObject) throws Exception
    {
        List<ConfigurationPropertyXmlType> jaxbConfiguration = new ArrayList<>();
        Iterator<String> keys = javaObject.getKeys();
        while (keys.hasNext())
        {
            String key = keys.next();
            ConfigurationPropertyXmlType property = new ConfigurationPropertyXmlType();
            property.setKey(key);
            property.setValue(javaObject.getString(key));
            jaxbConfiguration.add(property);
        }

        return jaxbConfiguration;
    }

    @Override
    public CompositeConfiguration unmarshal(final Object jaxbObject) throws Exception
    {
        BetterBaseConfiguration configuration = new BetterBaseConfiguration();
        for (ConfigurationPropertyXmlType property : (List<ConfigurationPropertyXmlType>) jaxbObject)
        {
            configuration.setProperty(property.getKey(), property.getValue());
        }

        return configuration;
    }

}

Name/value class:

public class ConfigurationPropertyXmlType
{
    private String key;
    private String value;

    public String getKey()
    {
        return key;
    }

    public String getValue()
    {
        return value;
    }

    public void setKey(final String key)
    {
        this.key = key;
    }

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

EclipseLink mapping file:

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings version="2.5" xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
        http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_5.xsd"
    package-name="myapp.configuration">

    <xml-schema element-form-default="QUALIFIED">
        <xml-ns prefix="mynm" namespace-uri="http://mynamespace" />
    </xml-schema>

    <java-types>
        <java-type name="myapp.configuration.BetterBaseConfiguration" >
            <xml-java-type-adapter value="myapp.configuration.JAXBConfigurationAdapter" type="myapp.configuration.BetterBaseConfiguration" />
            <xml-root-element name="Configuration" />
        </java-type>
    </java-types>

</xml-bindings>

Desired output:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <name>some name</name>
        <value>some value</value>
    </property>
</configuration>

回答1:


EclipseLink MOXy and other JAXB (JSR-222) providers do not apply an XmlAdapter to the root object being marshalled. You can explicitly call the adapter logic before doing a marshal or after doing an unmarshal.



来源:https://stackoverflow.com/questions/21640566/using-an-adapter-to-marshal-a-class-to-a-root-element-with-moxy-or-any-other-jax

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!