簡體   English   中英

接口和 jaxb

[英]Interfaces and 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 嗎?

您可以使用@XmlElement注釋來指定接口字段/屬性的實現類型。

@XmlAccessorType(XmlAccessType.FIELD)
public class Event{

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

}

更多信息

我不確定它會起作用,但是您是否嘗試使用抽象類而不是接口?

我想知道 JaxB 需要實例化類來進行轉換......

我知道可以使用@XmlAnyElement來避免在包含接口作為元素的類的編組@XmlAnyElement時出錯。 這導致了一個缺點,即解組時的類型。 如果您使用@XmlAnyElement(lax=true)並在具體類上指定具有特定名稱的@XmlRootElement或在正在解組的元素上指定 xsi:type ,它將完美地解組到您的具體類。 我不知道如何做后者,但前者使用@XmlRootElement(name="my-concrete-element")非常簡單( @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 出現在具體類中,我將不勝感激分享解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM