2

我有三个第 3 方不可变对象(Foo、Bar、BarFactory)和 binding.xml。我想在 binding.xml 中标记第 3 方不可变对象,但 JAXB 需要零参数构造函数。在 JAXB 和 MOXy 中编组这些类是不可能的吗?

Foo、Bar、BarFactory、演示代码 binding.xml 如下。

package example.bindingfile;

public class Foo{
    public static Foo getInstance(int value1, float value2){
        return new Foo(value1, value2);
    }
    private final int value1;
    private final float value2;
    private Foo(int value1, float value2){
        this.value1 = value1;
        this.value2 = value2;
    }
    public int getValue1(){
        return value1;
    }
    public float getValue2(){
        return value2;
    }
}

package example.bindingfile;
public class Bar{
    private final int value;
    Bar(int value){
        this.value = value;
    }
    public int getValue(){
        return value;
    }
}

package example.bindingfile;
public class BarFactory{
    private BarFactory(){}
    public static Bar getInstance(int value){
        return new Bar(value);
    }
}

binding.xml,自定义的 ClassExtractor 和演示类如下。

--- 绑定.xml

<?xml version="1.0"?>
    <xml-bindings
    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_3.xsd"
    version="2.3"
    package-name="example.bindingfile">
    <xml-schema
        namespace="http://www.example.com/bindingfile"
        element-form-default="QUALIFIED"/>
    <java-types>
        <!--
        <java-type name="Foo" xml-accessor-type="FIELD">
            <xml-root-element/>
            <xml-type prop-order="value1 value2"/>
            <java-attributes>
                <xml-element java-attribute="value1" name="val1"/>
                <xml-element java-attribute="value2" name="val2"/>
            </java-attributes>
        </java-type>
        -->
        <java-type name="Bar" xml-accessor-type="PROPERTY">
            <xml-root-element/>
            <!--<xml-java-type-adapter value="example.bindingfile.BarAdapter"/>-->
            <xml-type prop-order="value"/>
            <xml-class-extractor class="example.bindingfile.BarExtractor"/>
            <java-attributes>
                <xml-element java-attribute="value" name="Value"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>
package example.bindingfile;

import org.eclipse.persistence.descriptors.ClassExtractor;
import org.eclipse.persistence.descriptors.MethodClassExtractor;
import org.eclipse.persistence.sessions.Record;
import org.eclipse.persistence.sessions.Session;

public class BarExtractor extends MethodClassExtractor{
    public BarExtractor(){}
    @Override public Class extractClassFromRow(Record databaseRow, Session session){
        return BarFactory.class;
    }
    @Override public String getClassExtractionMethodName(){
        return "getInstance";
    }
}
package example.bindingfile;

import java.io.File;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextFactory;

public class Demo{
    public static void main(String[] args) throws Exception{
        Map<String, Object> properties = new HashMap<String, Object>(1);
        List<Object> bindingFileList = new ArrayList<Object>(1);
        bindingFileList.add("example/bindingfile/binding.xml");
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, bindingFileList);
        JAXBContext jc = JAXBContext.newInstance(new Class[]{Bar.class}, properties);
    //JAXBContext jc = JAXBContext.newInstance(Bar.class);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(BarFactory.getInstance(1), System.out);
    }
}

和 example.bindingfile.Demo 抛出异常。

Exception in thread "main" javax.xml.bind.JAXBException: 
Exception Description: The class example.bindingfile.Bar requires a zero argument constructor or a specified factory method.  Note that non-static inner classes do not have zero argument constructors and are not supported.
 - with linked exception:
[Exception [EclipseLink-50001] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.JAXBException
Exception Description: The class example.bindingfile.Bar requires a zero argument constructor or a specified factory method.  Note that non-static inner classes do not have zero argument constructors and are not supported.]
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:926)
    at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:163)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:171)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:158)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:118)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:108)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:248)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:235)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:385)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:637)
    at example.bindingfile.Demo.main(Demo.java:16)
Caused by: Exception [EclipseLink-50001] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.JAXBException
Exception Description: The class example.bindingfile.Bar requires a zero argument constructor or a specified factory method.  Note that non-static inner classes do not have zero argument constructors and are not supported.
    at org.eclipse.persistence.exceptions.JAXBException.factoryMethodOrConstructorRequired(JAXBException.java:142)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.finalizeProperties(AnnotationsProcessor.java:826)
    at org.eclipse.persistence.jaxb.compiler.XMLProcessor.processXML(XMLProcessor.java:412)
    at org.eclipse.persistence.jaxb.compiler.Generator.<init>(Generator.java:145)
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:922)
    ... 14 more
4

1 回答 1

0

目前,您可以在EclipseLink MOXy 以及所有其他使用XmlAdapter.XmlAdapter

已打开以下增强请求以在 MOXy 中原生支持多参数构造函数。您可以将您的投票添加到此增强功能中,以帮助将其提高优先级。

于 2013-01-24T11:34:09.247 回答