1

我将向您展示我的代码,它会更清楚:

@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 吗?

4

3 回答 3

0

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

@XmlAccessorType(XmlAccessType.FIELD)
public class Event{

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

}

了解更多信息

于 2013-10-10T10:11:02.600 回答
0

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

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

于 2013-10-10T10:11:24.617 回答
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 出现在具体类中,我将不胜感激分享解决方案。

于 2020-04-30T14:07:44.930 回答