JAXB和枚举实现接口

时间:2016-05-05 10:02:33

标签: java jaxb2

我是JAXB的新手(也是Stackoverflow的新手!)并且在尝试编组和解组包含实现接口的枚举列表的对象时遇到了问题。 我看了here,我尝试了一个类似的例子:

public class testXML {
    private static interface Animal {
        public String getName();
    }

    @XmlRootElement
    private static class Lion implements Animal {
        @XmlElement
        private String name;
        public Lion() { name = "Lion"; }
        @Override public String getName() {
            return name;
        }
    }

    @XmlRootElement
    private static class Dog implements Animal {
        @XmlElement
        private String name;
        public Dog() { name = "Dog"; }
        @Override public String getName() {
            return name;
        }
    }

    @XmlRootElement
    private static class Zoo {
      @XmlElementRefs({
          @XmlElementRef(name = "lion", type = Lion.class, required = true),
          @XmlElementRef(name = "dog", type = Dog.class, required = true)
      })
      public List<Animal> animals;
      public Zoo(Animal ... animals) {
          this.animals = Arrays.asList(animals);
      }
      public Zoo() {
          animals = null;
      }
      public Animal getAnimal(int i) {
          return animals.get(i);
      }
    }

    public static void main(String[] args) throws JAXBException {
        File file = new File("testXML.xml");
        JAXBContext context = JAXBContext.newInstance(
                Zoo.class,
                Lion.class,
                Dog.class);
        //SerializableParameter<ChannelParamEnum> result = new SerializableParameter(ChannelParamEnum.PARAM_CH_FGAIN, 1.0);
        Zoo result = new Zoo(new Lion(), new Dog());
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(result, file);

        Zoo unmar = (Zoo)context.createUnmarshaller().unmarshal(file);
        Animal anim = unmar.getAnimal(0);
        System.out.println(anim);
    }
}

这没有问题。然后我尝试将Lion和Dog类转换为枚举并尝试以下方法:

public class testXML {
    private static interface Animal {
        public String getName();
    }

    @XmlRootElement
    private static enum Lion implements Animal {
        SIMBA("Simba"),
        MUFASA("Mufasa"),
        SCAR("Scar");

        private String name;
        Lion(String name) { this.name = name; }
        @Override public String getName() {
            return name;
        }
    }

    @XmlRootElement
    private static enum Dog implements Animal {
        PONGO("Pongo"),
        PEGGY("Peggy");

        private String name;
        Dog(String name) { this.name = name; }
        @Override public String getName() {
            return name;
        }
    }

    @XmlRootElement
    private static class Zoo {
      @XmlElementRefs({
          @XmlElementRef(name = "lion", type = Lion.class),
          @XmlElementRef(name = "dog", type = Dog.class)
      })
      public List<Animal> animals;
      public Zoo(Animal ... animals) {
          this.animals = Arrays.asList(animals);
      }
      public Zoo() {
          animals = null;
      }
      public Animal getAnimal(int i) {
          return animals.get(i);
      }
    }

    public static void main(String[] args) throws JAXBException {
        File file = new File("testXML.xml");
        JAXBContext context = JAXBContext.newInstance(
                Lion.class,
                Dog.class,
                Zoo.class);
        Zoo result = new Zoo(Lion.SIMBA, Lion.SCAR, Dog.PONGO);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(result, file);

        Zoo unmar = (Zoo)context.createUnmarshaller().unmarshal(file);
        Animal anim = unmar.getAnimal(0);
        System.out.println(anim);
    }
}

此代码在运行时在JAXBContext.newInstance中失败

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Invalid @XmlElementRef : Type "package.testXML$Lion" or any of its subclasses are not known to this context.

显然这不是我的用例,我必须使用枚举而不是类。我环顾四周,但没有找到答案,所以非常感谢任何帮助。

谢谢!

1 个答案:

答案 0 :(得分:1)

最后我找到了解决方案。这足以改变

  @XmlElementRefs({
      @XmlElementRef(name = "lion", type = Lion.class),
      @XmlElementRef(name = "dog", type = Dog.class)
  })

  @XmlElements({
      @XmlElement(name="lion", type=Lion.class),
      @XmlElement(name="dog", type=Dog.class)
  })

无论如何,我仍然觉得我在JAXB利用方面缺少很多东西。

我希望这有帮助!