有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

绑定中使用Moxy的java接口映射。xml不能使用多个接口?

我正在尝试使用Moxy v2。5.2约束力。xml映射类作为注释的替代,因为我不能将注释放在第三方父类中

编辑:在收到Blaise的反馈后,我修改了下面的部分

由于父接口,我似乎无法映射接口

java代码片段:

    public final class CmsContent {
        private ContentItemGroup group;
   .... getter/setters
 }

public class ContentItemGroupDefault extends CoreKeyBase implements ContentItemGroup {
    private String bla;
   .... getter/setters
}

绑定文件:

<xml-bindings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" 
    package-name="com.core.domain" xml-mapping-metadata-complete="true" xml-accessor-type="NONE">

    <java-types>
        <java-type name="CmsContent" super-type="java.lang.Object" xml-accessor-type="NONE" >
            <xml-root-element name="content" />
            <java-attributes>
                <xml-element java-attribute="group" name="group" type="com.core.domain.impl.ContentItemGroupDefault" />
            </java-attributes>
        </java-type>

        <java-type name="ContentItemGroupDefault" super-type="java.lang.Object" xml-accessor-type="NONE">
            <java-attributes>
                <xml-attribute java-attribute="id" name="key"  /> <!-- from parent class -->
                <xml-transient java-attribute="name" />
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

以及封送它的代码:

final Map<String, Object> properties = new HashMap<String, Object>();
final InputStream bindings = CmsContent.class.getResourceAsStream("jaxb-binding.xml");
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, bindings);
final Class<?>[] classes = new Class<?>[] { CmsContent.class};
final JAXBContext context = JAXBContext.newInstance(classes, properties);
final Marshaller marshaller = context.createMarshaller();

final CmsContent content = createCmsContent();
marshaller.marshal(content, System.out);

著名的例外是:

The java interface com.core.domain.ContentItemGroup can not be mapped by JAXB as it has multiple mappable parent interfaces. Multiple inheritence is not supported

注意:@Blaise下面的例子运行得很好,谢谢,但是这个例子没有像我的例子中那样的多个父类,这导致了异常,甚至在绑定xml中我使用了super-type属性

调试Moxy代码后,当Moxy类“AnnotationsProcessor”扫描CmsContent的所有属性并试图发现CmsContent中的属性ContentItemGroup是否为集合、方法:Helper时,会发生异常。isCollectionType(..)

在Moxy方法JavaClassImpl中。getSuperclass(…),它将遍历接口ContentItemGroup属性的所有父类,并将失败,因为父类不是以“java”或“javax”开头的。 注意:接口ContentItemGroup扩展了2个接口

为什么它失败了,它不使用绑定xml中定义的超类型吗

如果ContentItemGroup不从任何接口扩展,或者它从单个接口扩展(这也适用于所有扩展父接口),则它可以工作。在这种情况下,它将成功地通过下面的方法。 但是,删除父接口不是一个选项:(

其他问题: 顺便说一句:当它工作时,如何将ContentItemGroupDefault父类的属性输出为xml属性?在上面的示例中,父类的“id”不会出现在xml中。在删除“super-type”属性的情况下,所有父类属性都会显示在输出中,即使我将它们标记为“transient”。我做错了什么

方法是JavaClassImpl。getSuperclass(…):

public JavaClass getSuperclass() {
    if(this.superClassOverride != null) {
        return this.superClassOverride;
    }
    if(jClass.isInterface()) {
        Class[] superInterfaces = jClass.getInterfaces();
        if(superInterfaces != null) {
            if(superInterfaces.length == 1) {
                return javaModelImpl.getClass(superInterfaces[0]);
            } else {
                Class parent = null;
                for(Class next:superInterfaces) {
                    if(!(next.getName().startsWith("java.") || next.getName().startsWith("javax."))) {
                        if(parent == null) {
                            parent = next;
                        } else {
                            throw JAXBException.invalidInterface(jClass.getName());
                        }
                    }
                }
                return javaModelImpl.getClass(parent);
            }
        }
    }
    return javaModelImpl.getClass(jClass.getSuperclass());
}

更新:

@BLAISE:    <java-type name="AbstractCmsContent" xml-transient="true">

将绑定xml ContentItemGroupDefault更改为(添加xml瞬态)时:

<java-type name="ContentItemGroupDefault" super-type="java.lang.Object" xml-accessor-type="NONE" xml-transient="true">

我确实得到了以下例外情况:

Exception Description: A descriptor for class com.core.cms.moxy.ContentItemGroupDefault was not found in the project.  For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.

我不明白。此外,将ContentItemGroupDefault添加到JAXContent时,也没有效果。 将“xml transient”属性添加到CmsContent映射时,将导致相同的异常,但随后会涉及CmsContent类

更新: 在此期间,我通过直接使用Woodstox修复了它,包括测试在内,这花费了我大约4个小时的时间。经过几天的挫折,我似乎没有让Moxy执行简单的映射。即使我犯了错误,我认为对于这些简单的元映射,Moxy可以变得更友好/更容易访问。 当将多个接口添加到@Blaise的PhoneNumber接口时,下面的示例显示了相同的“多接口支持”错误。 我想使用Moxy,就像我在平台的其他地方使用它一样,它涉及数千个生成的、工作良好的jaxb类。但是,一个简单的映射案例似乎很难(


共 (1) 个答案

  1. # 1 楼答案

    当您有一个面向接口的模型时,它实际上是您映射的支持实现类。下面是我的一个示例的链接,该示例演示了如何使用注释实现这一点

    下面的链接示例将是相应的映射文档:

    <?xml version="1.0"?>
    <xml-bindings
        xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
        package-name="blog.interfaces">
        <java-types>
            <java-type name="CustomerImpl">
                <xml-root-element name="customer"/>
                <java-attributes>
                    <xml-element java-attribute="address" type="blog.interfaces.AddressImpl"/>
                    <xml-element java-attribute="phoneNumbers" name="phone-number" type="blog.interfaces.PhoneNumberImpl"/>
                </java-attributes>
            </java-type>
            <java-type name="PhoneNumberImpl">
                <java-attributes>
                    <xml-value java-attribute="value"/>
                </java-attributes>
            </java-type>
        </java-types>
    </xml-bindings>
    

    更新

    Thanks @Blaise. With your feedback I isolated the problem further and updated the above code example. Moxy doesn't like multiple parent interfaces (your code example works fine, but has no multiple interfaces)... Please feedback?

    只有当您试图将接口视为映射对象时,才会出现多父接口问题。我的建议是不要这样做。是否有任何地方没有将a属性重写为实际的实现类型

    我无法重现您看到的错误。但需要注意的是,当您执行以下操作时,实际上是在告诉MOXy这个类的超类是Object。就MOXy而言,它不会处理CmsContent的真正超类

    <java-type name="CmsContent" super-type="java.lang.Object" xml-accessor-type="NONE" >
    

    如果您只想将CmsContent的超类视为简单的未映射,并将属性视为子类的属性,那么您可以将该类标记为@XmlTransient。这是在XML元数据中完成的,如:

    <java-type name="AbstractCmsContent" xml-transient="true">