3

下面显示的 JUnit 测试使用 MOXy 失败(在我的环境中),但适用于 JAXB 参考实现。

预期生成的 XML 是:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<itemManager>
    <items>
        <value>2</value>
    </items>
</itemManager>

但打开 MOXy - jaxb.properties 包含:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

生成的 XML 字符串为空。

这种行为的原因可能是什么以及需要做些什么来解决它?

我已经尝试过 EclipseLink MOXy 版本 2.5.1 和 2.4.2 - 请参阅下面的 pom.xml 片段。依赖项是 pom.xml 中的第一个依赖项,然后是许多其他依赖项(这也可能破坏了节目)。

<!-- Eclipselink moxy -->
<dependency>
  <groupId>org.eclipse.persistence</groupId>
  <artifactId>org.eclipse.persistence.moxy</artifactId>
  <version>2.4.2</version> 
  <!--  <version>2.5.1</version>   -->
  <scope>test</scope>
</dependency>

JUnit 测试的 Java 代码:

package com.bitplan.storage.moxy;

import static org.junit.Assert.*;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import org.junit.Test;

/**
 * show problem with empty xml result for Jaxb Marshaller
 * 
 * @author wf
 * 
 */
public class TestEmptyXml {

    public interface Copyable<T> {
        /**
         * copy me from the copyable
         * 
         * @param othe
         *          - the source copyaqble to copy from
         */
        public void copyFrom(T other);
    }

    public interface BO<BO_T> extends Copyable<BO_T> {

    }

    public interface ItemInterface {

    }

    @XmlRootElement
    public static class Item implements ItemInterface {
        int value;

        /**
         * @return the value
         */
        public int getValue() {
            return value;
        }

        /**
         * @param value
         *          the value to set
         */
        public void setValue(int value) {
            this.value = value;
        }

        public Item() {

        }

        public Item(int pValue) {
            value = pValue;
        }

    }

    public interface ItemManagerInterface {
        public void setItems(List<Item> pItems);

        public List<Item> getItems();
    }

    public interface MoxyList<BO_T> extends Collection<BO_T> {

    }

    public interface MoxyManager<BO_T> extends MoxyList<BO_T> {
    }

    public static class MoxyManagerImpl<BO_T> implements MoxyManager<BO_T> {
        public transient List<BO_T> bolist = new ArrayList<BO_T>();

        @Override
        public boolean add(BO_T arg0) {
            boolean result = bolist.add(arg0);
            return result;
        }

        @Override
        public boolean addAll(Collection<? extends BO_T> arg0) {
            boolean result = bolist.addAll(arg0);
            return result;
        }

        @Override
        public void clear() {
            bolist.clear();
        }

        @Override
        public boolean contains(Object arg0) {
            boolean result = bolist.contains(arg0);
            return result;
        }

        @Override
        public boolean containsAll(Collection<?> arg0) {
            boolean result = bolist.containsAll(arg0);
            return result;
        }

        @Override
        public boolean isEmpty() {
            boolean result = bolist.isEmpty();
            return result;
        }

        @Override
        public Iterator<BO_T> iterator() {
            Iterator<BO_T> result = bolist.iterator();
            return result;
        }

        @Override
        public boolean remove(Object arg0) {
            boolean result = bolist.remove(arg0);
            return result;
        }

        @Override
        public boolean removeAll(Collection<?> arg0) {
            boolean result = bolist.removeAll(arg0);
            return result;
        }

        @Override
        public boolean retainAll(Collection<?> arg0) {
            boolean result = bolist.retainAll(arg0);
            return result;
        }

        @Override
        public int size() {
            int result = bolist.size();
            return result;
        }

        @Override
        public Object[] toArray() {
            Object[] result = bolist.toArray();
            return result;
        }

        @Override
        public <T> T[] toArray(T[] arg0) {
            T[] result = bolist.toArray(arg0);
            return result;
        }

    }

    @XmlAccessorType(XmlAccessType.NONE)
    @XmlTransient
    public static abstract class MyMoxyManager<BO_T> extends
            MoxyManagerImpl<BO_T> {
        public abstract Class<? extends BO<?>> getEntityType();

    }

    @XmlRootElement
    public static class ItemManager extends MyMoxyManager<Item> implements
            ItemManagerInterface {
        public ItemManager() {

        }

        private List<Item> items = new ArrayList<Item>();

        @Override
        @XmlElement
        public void setItems(List<Item> pItems) {
            items = pItems;
        }

        @Override
        public List<Item> getItems() {
            return items;
        }

        @SuppressWarnings("unchecked")
        @Override
        public Class<? extends BO<?>> getEntityType() {
            return (Class<? extends BO<?>>) Item.class;
        }
    }

    /**
     * convert the target to XML Format
     * 
     * @param target
     * @return
     * @throws Exception
     */
    public String asXML(Object target) throws Exception {
        JAXBContext jaxbContext = JAXBContext.newInstance(target.getClass());
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        // output pretty printed
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        StringWriter sw = new StringWriter();
        jaxbMarshaller.marshal(target, sw);
        String result = sw.toString();
        return result;
    }

    @Test
    public void testMarshall() throws Exception {
        ItemManager im = new ItemManager();
        im.items.add(new Item(2));
        String xml = asXML(im);
        System.out.println(xml);
        assertNotEquals("xml should not be empty", "", xml);
    }

}
4

1 回答 1

0

在您的示例中target,正在编组的参数是ItemManager. 由于下面的类组织 MOXy 最终认为这ItemManager是一个集合而不是域对象,这就是为什么会发生奇怪的事情。

  • ItemManager-扩展->MyMoxyManager
  • MyMoxyManager-扩展->MoxyManagerImpl
  • MoxyManagerImpl-实现->MoxyManager
  • MoxyManager-扩展->MoxyList
  • MoxyList-扩展->Collection

我仍然需要调查这个用例的正确行为应该是什么。您能否继续为这个问题打开一个错误。

于 2013-10-15T14:13:27.297 回答