接口和jaxb

时间:2013-10-10 09:26:27

标签: java xml interface jaxb

我会告诉你我的代码会更清楚:

@XmlRootElement
FilePollerConf{

    ArrayList<Directory> directoriesList = new ArrayList<Directory>();

}

Directory{

    ArrayList<Match> matchList = new ArrayList<Match>();

}

Match{

    ArrayList<Event> eventsList = new ArrayList<Event>();

}

Event{

    ArrayList<IAction> actionsList = new ArrayList<IAction>();

}

IAction{

    void send();

}

这一点,当我尝试用jaxb解组时,我有错误:

  

IAction是一个接口,JAXB无法处理接口。

所以我找了@XmlAdapter,但我没有看到像我这样的用例,所以我真的不知道我是否可以使用它?我继续搜索,但如果你有一个想法,它可能是受欢迎的!我已经拥有了我的xml,我希望jaxb生成我(给你xml):

<?xml version="1.0" encoding="utf-8"?>
<FilePollerConfiguration>
    <Directory path="C://Users//jmoreau040612//Desktop//Old">
        <Match pattern="*.xml">
       <Event name="create">
           <FTPSend>
          <FTPServer>toto.com</FTPServer>
          <FTPPort>21</FTPPort>
          <Login>toto</Login>
          <Password>titi</Password>
          <destinationPath>/root/src</destinationPath>
      </FTPSend>
       </Event>
   </Match>
        <Match pattern="*.csv">
       <Event name="modify">
           <MailSend>
          <Name>MailSend</Name>
          <SMTPServer>smtp.fr.gric</SMTPServer>
          <SMTPPort>25</SMTPPort>
          <MailTo>toto@rock.com</MailTo>
          <MailFrom>titi@rock.com</MailFrom>
          <Subject>tata</Subject>
          <Body>blabla</Body>
      </MailSend>
       </Event>
   </Match>
    </Directory>
    <Directory path="C://Users//jmoreau040612//Desktop//New">
        <Match pattern="*.csv">
       <Event name="create">
           <ServerToServer>
                    <location>ergrthrhdrth</location>
                    <destination>ergergeg</destination>
                </ServerToServer>    
       </Event>
   </Match>
   <Match pattern="*.csv">
       <Event name="delete">
           <SFTPSend>
          <SFTPServer>toto.sgcib.com</SFTPServer>
          <SFTPPort>21</SFTPPort>
          <Login>toto</Login>
          <Password>titi</Password>
          <destinationPath>/root/src</destinationPath>
          <PrivateKeyFile>C://Desktop/privatekey.prk</PrivateKeyFile>
      </SFTPSend>
       </Event>
   </Match>
    </Directory>
</FilePollerConfiguration>

关键是我的结构不会总是一样,所以我可以使用jaxb吗?

3 个答案:

答案 0 :(得分:0)

您可以使用@XmlElement注释指定接口字段/属性的implmenentation类型。

@XmlAccessorType(XmlAccessType.FIELD)
public class Event{

    @XmlElement(type=ActionImpl.class)
    ArrayList<IAction> actionsList = new ArrayList<IAction>();

}

了解更多信息

答案 1 :(得分:0)

我不确定它是否会起作用,但您是否尝试使用抽象类而不是接口?

我想知道JaxB需要实现类来进行转换......

答案 2 :(得分:0)

我知道可以使用@XmlAnyElement来避免在对包含接口作为元素的类进行编组和解组时出错。这就导致了一个缺点,那就是解组时的类型。如果您使用@XmlAnyElement(lax=true)并在具体类上指定具有特定名称的@XmlRootElement或在要解组的元素上指定xsi:type,那么它将对您的具体类完全解组。我不知道该怎么做,但是前者的使用非常简单(@XmlRootElement(name="my-concrete-element"))。

举个例子:

public interface Abstract {

    public void setData(String data);
    public String getData();

}

@XmlRootElement(name = "concrete1")
@XmlAccessorType(XmlAccessType.FIELD)
public class Concrete1 implements Abstract {

    @XmlElement
    private String data;

    @Override
    public void setData(String data) {
        this.data = data;
    }

    @Override
    public String getData() {
        return this.data;
    }

    @Override
    public String toString() {
        return "@Concrete1{data: " + this.data + "}";
    }

}

@XmlRootElement(name = "concrete2")
@XmlAccessorType(XmlAccessType.FIELD)
public class Concrete2 implements Abstract {

    @XmlElement
    private String data;

    @Override
    public void setData(String data) {
        this.data = data;
    }

    @Override
    public String getData() {
        return this.data;
    }

    @Override
    public String toString() {
        return "@Concrete2{data: " + this.data + "}";
    }

}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlElement
    private String prop;

    @XmlElementWrapper(name = "abstracts")
    @XmlAnyElement(lax = true)
    private ArrayList<Abstract> abstracts;

    public void setAbstracts(ArrayList<Abstract> abstracts) {
        this.abstracts = abstracts;
    }

    public ArrayList<Abstract> getAbstracts() {
        return abstracts;
    }

    @Override
    public String toString() {
        String ret = "{prop: " + this.prop + ", abstracts: [";
        Object[] abstracts = this.abstracts.toArray();
        for(Object abstract: abstracts) {
            ret += abstract.toString() + ", ";
        }
        return ret + "]}";
    }

    public void setProp(String prop) {
        this.prop = prop;
    }

    public String getProp() {
        return prop;
    }

}

如果有人知道如何在不使用任何硬编码解决方案的情况下强制xsi:type出现在具体的类中,那么我希望能与您共享解决方案。