首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在不使用多个接口的binding.xml中使用Moxy进行接口映射?

在不使用多个接口的binding.xml中使用Moxy进行接口映射?
EN

Stack Overflow用户
提问于 2014-11-21 21:24:55
回答 1查看 798关注 0票数 1

我试图使用Moxy v2.5.2 binding.xml映射一个类,作为注释的替代,因为我不能将注释放在第三方父类中。

编辑:在Blaise的反馈之后,在下面修改了这个部分

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

java代码片段:

代码语言:javascript
复制
    public final class CmsContent {
        private ContentItemGroup group;
   .... getter/setters
 }

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

绑定文件:

代码语言:javascript
复制
<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>

以及编组它的代码:

代码语言:javascript
复制
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);

著名的例外是:

代码语言:javascript
复制
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示例运行良好,谢谢,但该示例没有像我这样的多个父类,这会导致异常,甚至在使用super属性的绑定xml中也是如此。

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

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

为什么会导致失败,而不使用绑定中定义的超级类型呢?

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

其他问题: xml :当它工作时,如何从父类输出属性作为属性?在上面的示例中,来自父类的"id“没有出现在xml中。如果我删除了“super”属性,所有父类属性都会出现在输出中,即使我将它们标记为“瞬态”时也是如此。我做错了什么?

JavaClassImpl.getSuperclass(..):方法

代码语言:javascript
复制
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());
}

更新:

代码语言:javascript
复制
@BLAISE:    <java-type name="AbstractCmsContent" xml-transient="true">

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

代码语言:javascript
复制
<java-type name="ContentItemGroupDefault" super-type="java.lang.Object" xml-accessor-type="NONE" xml-transient="true">

我确实得到了以下例外:

代码语言:javascript
复制
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-瞬态”属性添加到CmsContent映射时,它将导致相同的异常,但随后将涉及CmsContent类。

更新:在此期间,我通过直接使用Woodstox修复了它,这花费了我大约4个小时的时间,包括测试。在经历了几天的挫折之后,我似乎无法让Moxy执行简单的映射。即使我确实犯了错误,我认为对于这些简单的元映射,Moxy也可以变得更友好/更容易访问。当向@Blaise的PhoneNumber接口添加多个接口时--这是下面的示例--我确实得到了相同的“多接口支持”错误。我想使用Moxy,因为我在平台的其他地方使用它,这些地方涉及到成千上万个运行良好的生成的jaxb类。然而,简单的映射情况似乎很难。:(

EN

回答 1

Stack Overflow用户

发布于 2014-11-27 20:26:03

当您有一个接口前端模型时,实际上映射的是支持实现类。下面是我的一个示例的链接,该示例演示了如何使用注释完成此操作。

  • http://blog.bdoughan.com/2011/05/jaxb-and-interface-fronted-models.html

对于这个链接的例子,下面将是相应的映射文档:

代码语言:javascript
复制
<?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>

更新

谢谢@Blaise。通过您的反馈,我进一步隔离了问题,并更新了上面的代码示例。Moxy不喜欢多个父接口(您的代码示例工作良好,但没有多个接口).请给我反馈?

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

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

代码语言:javascript
复制
<java-type name="CmsContent" super-type="java.lang.Object" xml-accessor-type="NONE" >

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

代码语言:javascript
复制
<java-type name="AbstractCmsContent" xml-transient="true">
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27070614

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档